Re: [Haskell-cafe] Killer pickler combinators (was Time leak)
This should not be the case. The amount of work is the same regardless and the issues seem to be with _timing_. Passing in trace that writes to the screen with a lock sort of slows things down. I encourage you to actually build the code and see it for yourself. Thanks, Joel On Dec 21, 2005, at 10:26 AM, Tomasz Zielonka wrote: My guess is that without tweaks the threads allocate more, which increases the pressure on GC. Try to analyze the GC stats with and without tweaks. -- http://wagerlabs.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Neil Mitchell [EMAIL PROTECTED] writes: I would have actually said Hugs, and especially the Windows front end WinHugs was a lot more suitable for beginners than GHC, but the wiki page very much gives the other impression. Which page are you referring to? I went to look, but couldn't find any page discussing the compiler/interpreter options with reasonable detail and focus. -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Killer pickler combinators (was Time leak)
On Wed, Dec 21, 2005 at 10:33:12AM +, Joel Reymont wrote: My guess is that without tweaks the threads allocate more, which increases the pressure on GC. Try to analyze the GC stats with and without tweaks. This should not be the case. The amount of work is the same regardless and the issues seem to be with _timing_. Passing in trace that writes to the screen with a lock sort of slows things down. I was unclear. Of course, every thread does the same amount of work, but without tweaks the threads working together can manage to increase the amount of memory that is required at a given point in time. Take an example - you have a computation that requires 1MB of memory. If you run it sequentially 1000 times, you still need only 1MB of memory. But if you span 1000 threads simultaneously and run the computation it each of them, you may need even 1000 * 1MB of memory. This may cause problems with cache, swaping, etc. The other question is how GHC's garbage collection performance scale in such situations? Best regards Tomasz -- I am searching for a programmer who is good at least in some of [Haskell, ML, C++, Linux, FreeBSD, math] for work in Warsaw, Poland ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, 21 Dec 2005, Robin Green wrote: Henning Thielemann wrote: Starting with IO in Haskell is like starting LaTeX with rotating text and making it colorful. Not at all! Indeed IO _is_ complicated regardless of whether it is modelled by Monads in Haskell or differently in other languages. Rubbish! 10 PRINT WHAT IS YOUR NAME? 20 INPUT NAME IO isn't complicated in BASIC. I agree. Not that it's *really* complicated in haskell, though. I think all a tutorial needs to do is explain = means a definition, - means the left side is the result of the right side In order to show that x = getLine means that x is the function getLine while x - getLine means that x is the result of getLine Monads can come *way* later I think, but even then they're not difficult at all. Beginners should start with non-monadic functions in order to later avoid IO in their functions whereever possible. Whilst localising IO to a small part of the program is generally a good idea, beginners should not be scared off by the thought that IO in Haskell is so hard it has to be covered on page 94. This is not the case. It should be introduced on page 1. If people want Haskell to be treated as a practical language, not just something for doing academic teaching and research with, it should be taught as a practical language - which means that things like IO and space/time usage come to the forefront. I agree with this wholeheartedly. When I first started playing with Haskell, some of the tutorials made it look like it was very difficult to do anything practical with it because doing real input and output seemed like an advanced topic. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Robin Green wrote: Whilst localising IO to a small part of the program is generally a good idea, beginners should not be scared off by the thought that IO in Haskell is so hard it has to be covered on page 94. This is not the case. It should be introduced on page 1. As a newbie... I'll agree with Robin. I /did/ think that IO in Haskell was probably very difficult because it's covered in page 94. I skimmed through YAHT and IO is covered wyyy deep into the document. I haven't read that section yet, but there is a lot of content and to me it looked like it must be something difficult. I guess/hope that when I get around to reading it I'll find out that it's not as scary as it looks. If people want Haskell to be treated as a practical language, not just something for doing academic teaching and research with, it should be taught as a practical language - which means that things like IO and space/time usage come to the forefront. Until recently I thought of Haskell as something you would use for Calculus and the like. It seemed like a tool for academia. You may be interested to know that one of the reasons I started looking at Haskell just now was to help a friend understand Calculus (the other reason is that Haskell looks very cool). Cheers, Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Functions with side-effects?
Hi all, I'm a Haskell newbie and I don't really understand how Haskell deals with functions that really must have side-effects. Like a rand() function or getLine(). I know this has something to do with monads, but I don't really understand monads yet. Is there someone who might explain this in newbie terms? I don't need to understand the whole thing, I don't need a rand() function right this minute. I just want to understand how Haskell separates purely functional code from non-functional code (I understand that a rand() function is inevitably not functional code, right?) Cheers, Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
On Wed, 21 Dec 2005, Daniel Carrera wrote: Hi all, I'm a Haskell newbie and I don't really understand how Haskell deals with functions that really must have side-effects. Like a rand() function or getLine(). I know this has something to do with monads, but I don't really understand monads yet. Is there someone who might explain this in newbie terms? I don't need to understand the whole thing, I don't need a rand() function right this minute. I just want to understand how Haskell separates purely functional code from non-functional code (I understand that a rand() function is inevitably not functional code, right?) Well, it's *all* functional fundamentally but when people say non-functional in relation to Haskell code what they mean is in a monad. Monads, I believe, can be just thought of as containers for state. So like I said in an e-mail on the tutorial thread the only distinction you need to make is between = which is truly a statement of definition and not subject to change, and - which says that the left hand side is the result of the action of the right hand side. In terms of types, - strips away the monadic type. Note for example that if you want your main program to take in a string and then print it to the screen, it is *NOT* main = putStrLn . getLine (which was I first thought) or main = putStrLn (getLine) (which you might guess from the type sig) but rather main = do x - getLine putStrLn x Because you want putStrLn to act on the string that *resulted* from getLine, and not on getLine itself. I'd check out this link from HaWiki on monads, http://haskell.org/hawiki/MonadsAsContainers ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Robin Green wrote: If people want Haskell to be treated as a practical language, not just something for doing academic teaching and research with, it should be taught as a practical language - which means that things like IO and space/time usage come to the forefront. Strange, I always thought predictable, understandable and above all correct code would be the primary goal, with small and quick code coming later. To write interactive Haskell code well, you have to understand higher order functions. So the IO monad has to come late in any tutorial. Before that, IO should be restricted to the EVA principle (Eingabe, Verarbeitung, Ausgabe == Input, Processing, Output). It was a good principle in the 60s, and it still is. Unless you want to teach people to program as they would do in Basic, that is. Udo. -- You can pick your friends and you can pick your nose, but you can't pick your friend's nose. signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, 21 Dec 2005, Robin Green wrote: Henning Thielemann wrote: Starting with IO in Haskell is like starting LaTeX with rotating text and making it colorful. Not at all! Indeed IO _is_ complicated regardless of whether it is modelled by Monads in Haskell or differently in other languages. Rubbish! 10 PRINT WHAT IS YOUR NAME? 20 INPUT NAME IO isn't complicated in BASIC. IO is always complicated: It means sending messages, follow redirections, updating contents of windows, writing to disks etc. Nevertheless it may be easily accessible in some languages like BASIC. But it is important to separate IO from computations, also in languages where IO is easily accessible. Usually students start writing programs with much user interaction and it is hard to convince them of the advantages of programming interfaces. So I prefer starting a tutorial without IO, interaction in GHCi and Hugs should be enough for the beginning. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, 21 Dec 2005, Creighton Hogg wrote: I agree with this wholeheartedly. When I first started playing with Haskell, some of the tutorials made it look like it was very difficult to do anything practical with it because doing real input and output seemed like an advanced topic. The drawback is that I saw many Haskell programs implemented with IO read/write functions which could be easily implemented without IO, using laziness. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Udo Stenzel wrote: Strange, I always thought predictable, understandable and above all correct code would be the primary goal, with small and quick code coming later. Depends on what you mean by quick and small. Do you mean that the program should execute fast and have a small memmory foot-print? If so, I agree. If what you mean is that the programmer should be able to finish the project quickly and it shouldn't have too many lines of code, then I think those features are important. To write interactive Haskell code well, you have to understand higher order functions. That's scary, that you need advanced knowledge just to do IO. Unless you want to teach people to program as they would do in Basic, that is. I don't know what you mean by that. Cheers, Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Henning Thielemann wrote: IO is always complicated: I have never once thought it was complicated. All I've ever needed are print() and readLine() and those shouldn't be complicated IMO. And I wouldn't want to wait for page 120 to learn how to do that. My programs are not going to be useful if they can't get user input or produce output. I don't want to wait for page 120 to write my first useful program. So I prefer starting a tutorial without IO, interaction in GHCi and Hugs should be enough for the beginning. GHCi and Hugs are enough for the /beginning/ yes, but that doesn't mean that IO should go on chapter 7. How about putting it in chapter 2? Cheers, Daniel -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
On 21/12/05, Daniel Carrera [EMAIL PROTECTED] wrote: Hi all, I'm a Haskell newbie and I don't really understand how Haskell deals with functions that really must have side-effects. Like a rand() function or getLine(). I know this has something to do with monads, but I don't really understand monads yet. Is there someone who might explain this in newbie terms? I don't need to understand the whole thing, I don't need a rand() function right this minute. I just want to understand how Haskell separates purely functional code from non-functional code (I understand that a rand() function is inevitably not functional code, right?) Cheers, Daniel. Haskell separates pure functions from computations where side effects must be considered by encoding those side effects as values of a particular type. Specifically, a value of type (IO a) is an action, which if executed would produce a value of type 'a'. Some examples: getLine :: IO String putStrLn :: String - IO () -- note that the result value is an empty tuple. randomRIO :: (Random a) = (a,a) - IO a Ordinary Haskell evaluation doesn't cause this execution to occur. A value of type (IO a) is almost completely inert. In fact, the only IO action which can really be said to run in a compiled Haskell program is main. Now, so far, all this is great, but without a way to chain actions together end-to-end, we can't do a whole lot. So Haskell provides us with a few primitives for composing and chaining together IO actions. A simple one of these is: () :: IO a - IO b - IO b where if x and y are IO actions, then (x y) is the action that performs x, dropping the result, then performs y and returns its result. Great, we can now write programs which do multiple things: main = putStrLn Hello putStrLn World will print Hello and World on separate lines. However, we don't yet have a way to chain actions in which we are allowed to use the result of the first in order to affect what the second action will do. This is accomplished by the following operation, called 'bind': (=) :: IO a - (a - IO b) - IO b Now, if x is an IO action with a result of type 'a', and f is a function from values of type 'a' to actions with a result of type 'b', then x = f is the action that performs x, and captures its result, passing it to f, which then computes a second action to be performed. That action is then carried out, and its result is the result of the overall computation. That's a mouthful, but once you see it in use, perhaps the idea will become clearer: main = putStrLn Hello, what is your name? getLine = \name - putStrLn (Hello, ++ name ++ !) This is most of what we need. In fact, this bind function is really successful, and we can define () in terms of it: x y = x = const y In practice, it turns out to also be quite important to turn a value into an IO action which does nothing, and simply returns that value. This is quite handy near the end of a chain of actions, where we want to decide what to return ourselves, rather than leaving it up to the last action in the chain. So there's one more primitive, return :: a - IO a which does just that. Note that there is no function: unsafe :: IO a - a as this would defeat the referential transparency of Haskell -- applying 'unsafe' to the same IO action might return different things every time, and Haskell functions aren't allowed to behave that way. Now, I haven't really told you anything about monads in general yet. Most monads are actually rather unlike IO, but they do share the similar concepts of bind and return. For monads in general, see my tutorial MonadsAsContainers on the wiki :) Hope this helps - Cale ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, 21 Dec 2005, Henning Thielemann wrote: On Wed, 21 Dec 2005, Creighton Hogg wrote: I agree with this wholeheartedly. When I first started playing with Haskell, some of the tutorials made it look like it was very difficult to do anything practical with it because doing real input and output seemed like an advanced topic. The drawback is that I saw many Haskell programs implemented with IO read/write functions which could be easily implemented without IO, using laziness. Can you think of any examples of things like that? Given that I'm still learning how to take advantage of laziness it'd be pretty interesting. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
On 21/12/05, Cale Gibbard [EMAIL PROTECTED] wrote: On 21/12/05, Daniel Carrera [EMAIL PROTECTED] wrote: Hi all, I'm a Haskell newbie and I don't really understand how Haskell deals with functions that really must have side-effects. Like a rand() function or getLine(). I know this has something to do with monads, but I don't really understand monads yet. Is there someone who might explain this in newbie terms? I don't need to understand the whole thing, I don't need a rand() function right this minute. I just want to understand how Haskell separates purely functional code from non-functional code (I understand that a rand() function is inevitably not functional code, right?) Cheers, Daniel. Haskell separates pure functions from computations where side effects must be considered by encoding those side effects as values of a particular type. Specifically, a value of type (IO a) is an action, which if executed would produce a value of type 'a'. Some examples: getLine :: IO String putStrLn :: String - IO () -- note that the result value is an empty tuple. randomRIO :: (Random a) = (a,a) - IO a Ordinary Haskell evaluation doesn't cause this execution to occur. A value of type (IO a) is almost completely inert. In fact, the only IO action which can really be said to run in a compiled Haskell program is main. Now, so far, all this is great, but without a way to chain actions together end-to-end, we can't do a whole lot. So Haskell provides us with a few primitives for composing and chaining together IO actions. A simple one of these is: () :: IO a - IO b - IO b where if x and y are IO actions, then (x y) is the action that performs x, dropping the result, then performs y and returns its result. Great, we can now write programs which do multiple things: main = putStrLn Hello putStrLn World will print Hello and World on separate lines. However, we don't yet have a way to chain actions in which we are allowed to use the result of the first in order to affect what the second action will do. This is accomplished by the following operation, called 'bind': (=) :: IO a - (a - IO b) - IO b Now, if x is an IO action with a result of type 'a', and f is a function from values of type 'a' to actions with a result of type 'b', then x = f is the action that performs x, and captures its result, passing it to f, which then computes a second action to be performed. That action is then carried out, and its result is the result of the overall computation. That's a mouthful, but once you see it in use, perhaps the idea will become clearer: main = putStrLn Hello, what is your name? getLine = \name - putStrLn (Hello, ++ name ++ !) This is most of what we need. In fact, this bind function is really successful, and we can define () in terms of it: x y = x = const y In practice, it turns out to also be quite important to turn a value into an IO action which does nothing, and simply returns that value. This is quite handy near the end of a chain of actions, where we want to decide what to return ourselves, rather than leaving it up to the last action in the chain. So there's one more primitive, return :: a - IO a which does just that. Note that there is no function: unsafe :: IO a - a as this would defeat the referential transparency of Haskell -- applying 'unsafe' to the same IO action might return different things every time, and Haskell functions aren't allowed to behave that way. Now, I haven't really told you anything about monads in general yet. Most monads are actually rather unlike IO, but they do share the similar concepts of bind and return. For monads in general, see my tutorial MonadsAsContainers on the wiki :) Hope this helps - Cale Oh, just sent that, but there was one more point I wanted to make. You might see do-notation all over the place in real Haskell programs. In do-notation, our example program might look like: main = do putStrLn Hello, what is your name? name - getLine putStrLn (Hello, ++ name ++ !) This is in fact entirely equivalent to the above form, and is translated into it by the Haskell compiler. So whenever you see a do block, you can just imagine a chain of applications of () and (=), and some lambdas when appropriate to capture the results of actions. - Cale ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On 21/12/05, Daniel Carrera [EMAIL PROTECTED] wrote: Henning Thielemann wrote: IO is always complicated: I have never once thought it was complicated. All I've ever needed are print() and readLine() and those shouldn't be complicated IMO. And I wouldn't want to wait for page 120 to learn how to do that. My programs are not going to be useful if they can't get user input or produce output. I don't want to wait for page 120 to write my first useful program. For this much, see my reply to your message in the other thread :) IO in Haskell isn't really so bad if you take it the right way. However, we do have these really nice interactive environments for evaluating expressions. When I write a real application, often the last thing I write is 'main'. It's more fun to start with the core of the algorithm that I want to implement, or problem I want to solve, and work my way outward to the user interface. So perhaps it's more natural for a Haskell tutorial to start there. As a Haskell programmer, it's where I'd start to write my program. So I prefer starting a tutorial without IO, interaction in GHCi and Hugs should be enough for the beginning. GHCi and Hugs are enough for the /beginning/ yes, but that doesn't mean that IO should go on chapter 7. How about putting it in chapter 2? Cheers, Daniel -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Tutorial uploaded
Paul Moore [EMAIL PROTECTED] writes: One thing I'd consider adding is something along the lines of a section: == So how do I write Hello, world? == I've gone and done it. I've perhaps been heavy handed on the original page, so feel free to complain and/or fix it. -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
Thanks for all the help. I think things are much clearer now. And this bit: main = do putStrLn Hello, what is your name? name - getLine putStrLn (Hello, ++ name ++ !) Looks quite straight forward. I just wrote my very first IO program with Haskell: --//-- main = do x - getLine putStrLn( show(length x) ) --//-- That's not so scary. The next thing I need to figure out is how to act on the input data itself (not just its length). For example, if I wanted a program to output the nth element of the fibonacci sequence: --//-- $ ./fib 12 144 --//-- My first inclination would be to write it as: --//-- main = do x - getLine putStrLn( show(fib x) ) --//-- Of course that won't work because x is an IO String and 'fib' wants an Int. To it looks like I need to do a conversion IO a - b but from what Cale said, that's not possible because it would defeat the referential transparency of Haskell. Hmm... there must be a way to solve this problem though... In any event, thanks for the help. I'm learning :) Cheers, Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] IO
Interesting discussion ... I don't think it is necessary/desirable to relegate IO to `chapter 14'. First of all, IO is handled differently in Haskell as the language designers quite successfully resisted the temptation of impurity. However, you don't have to understand the full implications of IO to be able to use it (like you don't have to know the full English grammar to be able to speak English). I typically cover IO very early in a Haskell course and then again in `chapter 14' after a discussion of monads. (To motivate the need for a special treatment of IO, I often ask the students to put themselves into the position of a language designer who tries to add IO to a purely functional language.) So why is there a special `IO' type? The type serves to distinguish between values and effectful computations: `String' is the type of strings, `IO String' is the type of computations that deliver a string. This is why the `do' notation uses `-' instead of `='. ask :: String - IO String ask question = do { putStrLn question; answer - getLine; putStrLn Thanks!; return answer } Here, `answer' of type `String' is the result of the effectful computation `getLine' of type `IO String'. I think IO can be treated on this level, just using the `do'-notation (it is not necessary to explain that the do-notations is merely syntactic sugar for `=' which involves higher-order functions). One thing that is important to stress, however, is that `-' is a binder: the variable on the lhs is *bound* to value delivered by the rhs. In other words, `-' introduces a variable (it does not assign a value to a store). Consequently, in do { a - m1; a - m2; ... } the second occurrence of `a' shadows the first occurrence. It is useful to think of `IO' as a `description' of an effectful computation (it is very much like a TODO list; the list describes actions, which may or may not be executed). This is why something of type `IO a' is also a value: it may be stored in a data structure or passed to a function. This means you can program you own control structures: data IOTree a = Done (IO a) | Choice (IO Bool) (IOTree a) (IOTree a) execute :: IOTree a - IO a execute (Done action) = do { action } execute (Choice action left right) = do { b - action; if b then do { execute left } else do { execute right } } Now, if IO is only a `description' of an IO action, when is the IO action actually executed? Exactly when `main' is called: only the TODO list that is bound to `main' is executed. Consider main = do { head [putStrLn hello world, putStrLn too lazy] } HTH, Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
-- Message: 1 Date: Wed, 21 Dec 2005 10:48:08 + From: Robin Green [EMAIL PROTECTED] Subject: Re: [Haskell-cafe] Re: Tutorial uploaded Beginners should start with non-monadic functions in order to later avoid IO in their functions whereever possible. Whilst localising IO to a small part of the program is generally a good idea, beginners should not be scared off by the thought that IO in Haskell is so hard it has to be covered on page 94. This is not the case. It should be introduced on page 1. If people want Haskell to be treated as a practical language, not just something for doing academic teaching and research with, it should be taught as a practical language - which means that things like IO and space/time usage come to the forefront. Couldn't agree more. I show my students IO in the first lecture of their first programming course in the first term of their first year. A few lectures later I discuss it in more detail, and tell to think of an IO a as instructions on a piece of paper to produce an a. My students have no difficulty understanding the difference between being given 500 crowns (a value), and being given my ATM card and code with instructions how to work an ATM! Haskell IO is mystifed far too often in my opinion--it needn't be hard at all. John ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
On 21/12/05, Daniel Carrera [EMAIL PROTECTED] wrote: Thanks for all the help. I think things are much clearer now. And this bit: main = do putStrLn Hello, what is your name? name - getLine putStrLn (Hello, ++ name ++ !) Looks quite straight forward. I just wrote my very first IO program with Haskell: --//-- main = do x - getLine putStrLn( show(length x) ) --//-- That's not so scary. The next thing I need to figure out is how to act on the input data itself (not just its length). For example, if I wanted a program to output the nth element of the fibonacci sequence: --//-- $ ./fib 12 144 --//-- My first inclination would be to write it as: --//-- main = do x - getLine putStrLn( show(fib x) ) --//-- Of course that won't work because x is an IO String and 'fib' wants an Int. To it looks like I need to do a conversion IO a - b but from what Cale said, that's not possible because it would defeat the referential transparency of Haskell. Actually, you're closer than you think here. x is actually of type String! The problem is just that fib wants a number, so you need to read the string: main = do x - getLine putStrLn (show (fib (read x))) There's a handy name for the composite (putStrLn . show) called 'print', so you can write: main = do x - getLine print (fib (read x))) Cheers! - Cale ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
On Wed, 21 Dec 2005, Daniel Carrera wrote: Thanks for all the help. I think things are much clearer now. And this bit: main = do putStrLn Hello, what is your name? name - getLine putStrLn (Hello, ++ name ++ !) Looks quite straight forward. I just wrote my very first IO program with Haskell: --//-- main = do x - getLine putStrLn( show(length x) ) --//-- That's not so scary. The next thing I need to figure out is how to act on the input data itself (not just its length). For example, if I wanted a program to output the nth element of the fibonacci sequence: --//-- $ ./fib 12 144 --//-- My first inclination would be to write it as: --//-- main = do x - getLine putStrLn( show(fib x) ) --//-- Of course that won't work because x is an IO String and 'fib' wants an Int. To it looks like I need to do a conversion IO a - b but from what Cale said, that's not possible because it would defeat the referential transparency of Haskell. x is a String, getLine has type IO String. That's what I was getting at in one of my last e-mails. So you just need something that can read in a string and convert it to an int. Something like let y = (read x) putStrLn $ show $ fib y should work, yes? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, 21 Dec 2005, Creighton Hogg wrote: On Wed, 21 Dec 2005, Henning Thielemann wrote: The drawback is that I saw many Haskell programs implemented with IO read/write functions which could be easily implemented without IO, using laziness. Can you think of any examples of things like that? Given that I'm still learning how to take advantage of laziness it'd be pretty interesting. Some example for writing a text the IO oriented way: do putStrLn bla replicateM 5 (putStrLn blub) putStrLn end whereas the lazy way is putStr (unlines ([bla] ++ replicate 5 blub ++ [end])) You see that the construction of the text is separated from the output, but the effect is rather the same in both variants: The text is constructed simultaneously with output. You could also make the separation explicit: text :: String text = unlines ([bla] ++ replicate 5 blub ++ [end]) main = putStr text ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Am Dienstag, 20. Dezember 2005 20:07 schrieb Sebastian Sylvan: [...] It's sometimes beneficial to lie a bit when starting out. Perhaps say something like this is a simplified view of things, for all the gory details see chapter 19. Monadic IO is pretty darn cool, sadly that means that many tutorial authors are tempted to spend pages upon pages explaining exactly why it's cool and how it works, but that is NOT what most people starting out with the language need to read. I'm still looking for a good *practical* tutorial that I could recommend to newcomers. IO, data types and QuickCheck in the very first chapter, I say! Real program examples from the get go, and go into the theory on why this has been hard in FP before Haskell (or Monadic IO rather) much much later, so as to not scare people away. I think that there are cases where it's better to start with ordinary functional programming and come to I/O later. In my opinion, an example case would be teaching Haskell at a university. /S /W ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] A simple server (or how to do io).
On 21.12 01:13, Pupeno wrote: So, I install a signal handler with installHandler... and then ? how do I prevent the program for quiting ? am I missing some kind of event loop here ? Here is a small server program: main = performForkWithUnixySessionStuff work -- this is just for testing, replace with real implementation performForkWithUnixySessionStuff x = x work = do s1 - runStreamServer ... s2 - runDgramServer ... mv - newEmptyMVar installHandler someSignal (Catch (putMVar mv ())) Nothing takeMVar mv someCleanupActions killServer s1 killServer s2 For simple testing you might want to just use getLine to wait for the right time to exit. - Einar Karttunen ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Substring replacements
Am Mittwoch, 21. Dezember 2005 08:18 schrieb Branimir Maksimovic: From: Bulat Ziganshin [EMAIL PROTECTED] Reply-To: Bulat Ziganshin [EMAIL PROTECTED] To: Branimir Maksimovic [EMAIL PROTECTED] CC: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Substring replacements Date: Tue, 20 Dec 2005 23:55:22 +0300 Hello Branimir, Tuesday, December 20, 2005, 9:48:48 PM, you wrote: BM I've finally performed test on amd64 and result is a same as on intel. BM KMP always wins. So KMP is best suited for non indexed strings BM and I guess should be used in library as prefered search/replace method. BM This test favors straightforward search. i'm 90% sure that straightforward method must be faster for one-time searches. I'm far less sure of that. If you have a really short search-pattern, I think that probably straightforward search is indeed faster (at least, if the search-pattern isn't supplied at compile-time). But if you have a pattern of length 100, say, and lots of relatively long partial matches, chances are that KMP will move on something like 50 chars at once, which would have to be re-checked by straightforward. I've no idea, when that would outweigh the extra time of building the KMP-arrays, though. In my test -- extremely unrealistic, but provides a more or less worst case example -- straightforward must make roughly half a million character comparisons to pass each 'c', while KMP does 2000 (+/-2) (one way through the array and back), so there are situations where KMP definitely is faster. But ordinarily, on my computer, your version of straightforward is 10-15% faster than KMP (search-patterns are now supplied on the command line -- which has no big impact; searched string is able sea...; all compiled with -O2; NOINLINE makes no difference -- at least with optimisations on --; without optimisations, KMP suffers far worse than straightforward). KMP is O(m) while straightforward is O(m*n). Where m is the length of the input and n is the length of the searched-for pattern, I think? But these are worst-case complexities, I believe, ordinarily, straightforward will be O(m), too. your test may give better results with KMP algorithm just because you repeat the same search many times and it was automatically run-time compiled as described on the wiki page about KMP My results seem to witness against that. My test favors straightforward, in any other case KMP wins by order of magnitude. Can you give example tests? I think that straightfoirward is better then KMP with optimisations off is due more complex program. try to add {-# NOINLINE replace #-} to both programs and repeat comparision Greetings, Bane. Cheers, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Am Mittwoch, 21. Dezember 2005 11:48 schrieb Robin Green: [...] If people want Haskell to be treated as a practical language, not just something for doing academic teaching and research with, it should be taught as a practical language - which means that things like IO and space/time usage come to the forefront. So programming is only practical if it's deals with a lot of I/O? This is wrong, in my opinion. Take a compiler. The only I/O it does is some simple file I/O. The important part of the compiler doesn't deal with I/O at all. Best wishes, Wolfgang ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] YAHT Tutorial
Folks, I'm surprised Hal's tutorial is so less known. I recommend (and send) it to everybody who asks me. I like that it starts early with some IO and mainly promotes ghc/ghci. Hugs is a good tool as well (and I sometimes use it, too), but ghc is definitively the flagship with better error reporting, active maintainance and for producing fast code (if that is important). It's good that this tutorial is freely available, but some people prefer to have a proper textbook. I just wonder what happened to An Introduction to Computing (with Haskell). Manuel M. T. Chakravarty and Gabriele C. Keller. Pearson Education Australia, 2002. which is also available in german as Einführung in die Programmierung mit Haskell http://www.pearson-studium.de/main/main.asp?page=bookdetailsProductID=81781 It's not listed under http://www.haskell.org/bookshelf/ nor http://www.haskell.org/learning.html. Maybe it is hard to recommend a single tutorial without spoiling selling chances of others. In our teaching courses Simon Thompson: Haskell: The Craft of Functional Programming, is mostly used. Others find Paul Hudak: The Haskell School of Expression the best. I just see that the recent tutorial version contains Parsec (good) and FiniteMap (deprecated) examples. I would appreciate the chapter Advanced Techniques being filled (but know how much time that would cost). Thanks for your tutorial so far, Hal! Cheers Christian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Killer pickler combinators (was Time leak)
From: Joel Reymont [EMAIL PROTECTED] To: Haskell-Cafe Cafe haskell-cafe@haskell.org Subject: [Haskell-cafe] Killer pickler combinators (was Time leak) Date: Wed, 21 Dec 2005 02:39:43 + The original paper is at http://research.microsoft.com/ ~akenn/fun/ picklercombinators.pdf My adaptation is at http://wagerlabs.com/timeleak.tgz. This is a full repro case, data included. The issue is that with 1000 threads my serialization is taking a few seconds. Inserting a delay or passing in trace (see README and code) gets serialization time down to 0-1s, the way it should be. What gives? Try it for yourself and please let me know! This has easy explanation. I am learning haskell and your programs are great of that. In this code: do TOD time1 _ - getClockTime (kind, ix1) - unpickle puCmdType ptr ix TOD time2 _ - getClockTime (cmd', _) - unpickle (puCommand kind) ptr ix1 TOD time3 _ - getClockTime you get time multiple times. So if you lock whole operation nothing else will be executed while in this code and therefore you don;t have timeouts. But, without lock more threads you have, more time have to wait for operation to finish and therefore timeouts. Since I see that Haskell executes all this in single thread, lock just ensures that your operasion will not be interrupted, thereferore not time outs. But if you measure say 5000 reads cumulative time, you'll get same problem again. Let's say you have more then one worker thread and multiple CPU's. Only then situation will be better. Perhaps you'll get somewhat better perfromance with OS context switch, but not to avail, it is humpered with same problem. You need more CPU-s and worker threads in order to service such large number of tasks. Just measure how much requests can be serviced in reasonable time and limit on that. For single cpu lock will be ok, but for multiple CPU's you have to somehow say Haskell to spawn multiple workers (more then one). I would be glad to know how to tell run time to use more then one worker thread. Greetings, Bane. Thanks, Joel -- http://wagerlabs.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe _ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Daniel Carrera wrote: Depends on what you mean by quick and small. Do you mean that the program should execute fast and have a small memmory foot-print? I was referring to Robin's mentioning space/time usage, so yes, that's what I meant. To write interactive Haskell code well, you have to understand higher order functions. That's scary, that you need advanced knowledge just to do IO. Actually not. You need advanced knowledge to *avoid* doing IO. (If higher order functions like map, fold count as advanced.) A good, readable, maintainable Haskell program is almost completely pure and does very little IO. Of course you can write an IO-heavy program in the same style you'd use in C, but it would be exactly as ugly. Unless you want to teach people to program as they would do in Basic, that is. I don't know what you mean by that. You will soon. Once you get used to composing functions instead of sequencing actions, you'll appreciate the difference. Udo. -- Disco is to music what Etch-A-Sketch is to art. signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Creighton Hogg wrote: On Wed, 21 Dec 2005, Henning Thielemann wrote: The drawback is that I saw many Haskell programs implemented with IO read/write functions which could be easily implemented without IO, using laziness. Can you think of any examples of things like that? Given that I'm still learning how to take advantage of laziness it'd be pretty interesting. Here's another one: I've heard a fellow claim, Haskell is basically unsuitable to implement a compiler, because Haskell is weak at IO and everything needs IO, the lexer, the preprocessor, the parser, the pretty-printer, ... Can you imagine what convoluted mess he would write if he learned IO first? Therefore I think, if, say, chapter 6 includes A parser for Things is a function from Strings to a list of Things and Strings, then chapter 7 is the earliest that should include IO beyond getContents and putStr. The funny thing is, after the parser IO is simply another monad. At this point, the compiler becomes an imperative one-liner and lots of pure functions. Udo. -- I piss on you all from a considerable height. -- Louis Ferdinand Celine signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Robin Green wrote: I meant that for *many* but not all practical programming tasks, IO is important. ...web applications... Ha, wrong! A CGI script only needs getEnv, getContents and putStr, if it has persistent state, it also needs readFile and writeFile. Each of the five is called exactly once per invocation. The main function is boiler plate, the bulk of the logic is pure. Same for a web application server, only less IO. Compilers are atypical in this regard. You wouldn't believe what diverse applications could be summed up under compilers. Udo. -- If I ever write a GUI library for Haskell, I'm going to call it pointlesstif. -- Pseudonym on #haskell signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Am Mittwoch, 21. Dezember 2005 13:31 schrieb Daniel Carrera: Udo Stenzel wrote: Strange, I always thought predictable, understandable and above all correct code would be the primary goal, with small and quick code coming later. Depends on what you mean by quick and small. Do you mean that the program should execute fast and have a small memmory foot-print? If so, I agree. If what you mean is that the programmer should be able to finish the project quickly and it shouldn't have too many lines of code, then I think those features are important. I agree, and keeping the IO-part of your programmes small helps with that in my experience. And as Cale wrote, working from the pure core to the IO-coating is more fun (personal inclination, of course). But yes, people want to write interactive programmes soon, so I think Chapter 2: Basic I/O where putStr(Ln), print, getLine, getChar, maybe also readFile and writeFile/appendFile are introduced, do-notation and '-' are explained is a good idea. However, a section about Why a special IO-type, more comprehensive explanations to come and how to use Hugs/ghci to develop and test your algorithms should be definitely included. That's my tuppence, feel free to disagree. To write interactive Haskell code well, you have to understand higher order functions. That's scary, that you need advanced knowledge just to do IO. Unless you want to teach people to program as they would do in Basic, that is. I don't know what you mean by that. Cheers, Daniel. ditto! P.S.: In May, there was a 'Daniel Carrera' around, too. Isn't that a strange coincidence? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
On Wed, Dec 21, 2005 at 11:43:42AM +, Daniel Carrera wrote: Hi all, I'm a Haskell newbie and I don't really understand how Haskell deals with functions that really must have side-effects. Like a rand() function or getLine(). I know this has something to do with monads, but I don't really understand monads yet. Is there someone who might explain this in newbie terms? I don't need to understand the whole thing, I don't need a rand() function right this minute. I just want to understand how Haskell separates purely functional code from non-functional code (I understand that a rand() function is inevitably not functional code, right?) What everyone said about monads is great, but I'd just like to add that for rand() you don't strictly need a monad. With a bit of care, you could write rand() to be of type rand :: Int - [Int] where it accepts a seed value, and returns an infinite list of pseudorandom numbers. In one sense we haven't gone non-monadic here, since there is actually an instance of monad for [a], but you needn't actually write monadic code. The catch with this rand is that when you go to actually use the output, you need to thread this list of random numbers through your code, and need to be sure never to use the same random number twice. Which is why you'd really prefer to use a monad that could force you to obey the constraints of only using each random number once. For some uses, though, the above rand will be great, as long as you're using it for list manipulations, such as xoring a list of numbers with random numbers as a primitive form of encryption (or a strong form of encryption, if you use a strong random number generator). -- David Roundy http://www.darcs.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Udo Stenzel wrote: Unless you want to teach people to program as they would do in Basic, that is. I don't know what you mean by that. You will soon. Once you get used to composing functions instead of sequencing actions, you'll appreciate the difference. Ah. Yes, I do think I understand the difference (my math background is stronger than my programming background). Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On 12/21/05, John Hughes [EMAIL PROTECTED] wrote: -- Message: 1 Date: Wed, 21 Dec 2005 10:48:08 + From: Robin Green [EMAIL PROTECTED] Subject: Re: [Haskell-cafe] Re: Tutorial uploaded Beginners should start with non-monadic functions in order to later avoid IO in their functions whereever possible. Whilst localising IO to a small part of the program is generally a good idea, beginners should not be scared off by the thought that IO in Haskell is so hard it has to be covered on page 94. This is not the case. It should be introduced on page 1. If people want Haskell to be treated as a practical language, not just something for doing academic teaching and research with, it should be taught as a practical language - which means that things like IO and space/time usage come to the forefront. Couldn't agree more. I show my students IO in the first lecture of their first programming course in the first term of their first year. A few lectures later I discuss it in more detail, and tell to think of an IO a as instructions on a piece of paper to produce an a. My students have no difficulty understanding the difference between being given 500 crowns (a value), and being given my ATM card and code with instructions how to work an ATM! Haskell IO is mystifed far too often in my opinion--it needn't be hard at all. You should write a book, or at least a tutorial series! :-) The order in which you deal with Haskell subjects in your course is, imo, very close to ideal. It emphasizes Haskell as a real-world pracical langauge, rather then making it look like an academic toy langauge which can't be used for anything real-world. As I mentioned in an earlier message I have yet to come across a book or tutorial which does this right. It should treats the language from a practical point of view, with IO, QuickCheck generators, data types, GUI's etc. right up front, rather than avoiding it until chapter 19 and later. /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Daniel Fischer wrote: P.S.: In May, there was a 'Daniel Carrera' around, too. Isn't that a strange coincidence? That was myself, using a different email address. I didn't get too far with Haskell that time, but I remembered that I liked it, so I'm going back to it a bit now. But I'm still a newbie :) Notice that I was already familiar with a few, very basic concepts (what is functional programming?) Cheers, Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Killer pickler combinators (was Time leak)
Cale is a genius! This totally solves the timeouts. Why, though? The lock is only used at the end of the unpickling. Why does it help? On Dec 21, 2005, at 2:56 PM, Cale Gibbard wrote: By the way, when I was doing threadDelays, I meant: trace s = withMVar lock $ const $ threadDelay 20 In case you didn't try that. - Cale On 21/12/05, Joel Reymont [EMAIL PROTECTED] wrote: I'm not sure I buy this. Again, this helps: {-# NOINLINE lock #-} lock :: MVar () lock = unsafePerformIO $ newMVar () trace s = withMVar lock $ const $ putStrLn s and then in read_ cmd - read h trace trace is called _after_ all the timings in read so it should not affect the timings. You could basically say that the lock is at the end of read, after all the unpickling has been done. The other interesting thing is that replacing trace with delay _ = threadDelay 1 does not solve the issue. -- http://wagerlabs.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] Substring replacements
Hello Daniel, Wednesday, December 21, 2005, 5:20:18 PM, you wrote: BM I've finally performed test on amd64 and result is a same as on intel. BM KMP always wins. So KMP is best suited for non indexed strings BM and I guess should be used in library as prefered search/replace method. BM This test favors straightforward search. i'm 90% sure that straightforward method must be faster for one-time searches. DF I'm far less sure of that. If you have a really short search-pattern, I think DF that probably straightforward search is indeed faster sorry, i mean exactly that, answering proposition to add this to library as a PREFFERED method. imho, typical usage of these routines is for short enough patterns and searched strings -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On 12/21/05, Wolfgang Jeltsch [EMAIL PROTECTED] wrote: Am Dienstag, 20. Dezember 2005 20:07 schrieb Sebastian Sylvan: [...] It's sometimes beneficial to lie a bit when starting out. Perhaps say something like this is a simplified view of things, for all the gory details see chapter 19. Monadic IO is pretty darn cool, sadly that means that many tutorial authors are tempted to spend pages upon pages explaining exactly why it's cool and how it works, but that is NOT what most people starting out with the language need to read. I'm still looking for a good *practical* tutorial that I could recommend to newcomers. IO, data types and QuickCheck in the very first chapter, I say! Real program examples from the get go, and go into the theory on why this has been hard in FP before Haskell (or Monadic IO rather) much much later, so as to not scare people away. I think that there are cases where it's better to start with ordinary functional programming and come to I/O later. In my opinion, an example case would be teaching Haskell at a university. Well, I certainly disagree there. I'm not advocating going into a full-blown explanation of monads, just enough to actually be able to write a real stand-alone program after the first chapter. They only need to know that do-notation is for sequencing computations, and (-) is for binding a name to the result of a computation. That's it! You could spend the next ten chapters with coding examples that are not very IO-heavy, and lead with a good example of doing as much as possible in the pure world (as well as pointing out every now and then whenever a particularly good IO-separtion was achieved - to emphasize that it's good practice). When someone who has programmed before learns Haskell and gets the impression that IO is beeing left for later because it's hard they might think bah, what a rubbish language, IO in Visual Basic isn't hard at all!. /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Killer pickler combinators (was Time leak)
On Dec 21, 2005, at 2:56 PM, Cale Gibbard wrote: By the way, when I was doing threadDelays, I meant: trace s = withMVar lock $ const $ threadDelay 20 In case you didn't try that. I'm trying 5k threads and I still get delays at times. Using thread delay of 1, though. ./unstuff trace.dat unstuff: user error (ORANGE ALERT: 0s, 7s, SrvServerInfo, ix1: 6, size: 49722) unstuff: user error (ORANGE ALERT: 0s, 8s, SrvServerInfo, ix1: 6, size: 49722) unstuff: user error (ORANGE ALERT: 0s, 7s, SrvServerInfo, ix1: 6, size: 49722) unstuff: user error (ORANGE ALERT: 0s, 5s, SrvServerInfo, ix1: 6, size: 49722) unstuff: user error (ORANGE ALERT: 0s, 5s, SrvServerInfo, ix1: 6, size: 49722) unstuff: user error (ORANGE ALERT: 0s, 4s, SrvServerInfo, ix1: 6, size: 49722) unstuff: user error (ORANGE ALERT: 0s, 6s, SrvServerInfo, ix1: 6, size: 49722) -- http://wagerlabs.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
Am Mittwoch, 21. Dezember 2005 13:15 schrieb Creighton Hogg: [...] Monads, I believe, can be just thought of as containers for state. I would say that you are talking especially about the I/O monad here. A monad as such is a rather general concept like a group is in algebra. The important point of the integration of imperative programming in Haskell is not that it's done using monads. The point is that you have a specific type (IO) whose values are descriptions of I/O actions, and some primitive operations on IO values. The IO type together with two of these primitive operations forms a monad but this is secondary in my opinion. [...] Best wishes, Wolfgang ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
Creighton Hogg wrote: x is a String, getLine has type IO String. That's what I was getting at in one of my last e-mails. Hmm... let's see if I understand: * getLine() has type IO String. * The - will convert an IO String to a plain String * So if I do x - getLine() then x has the type String. So, the - effectively ammounts to an IO a - a conversion. In another email John Hughes said that one could think of IO a as a set of instructins for obtaining a. I guess that means that IO is a sort of imperative layer that helps the purely functional code interact with the outside world. So I can have an IO bit (e.g. a do-block) that calls functions (which are purely functional code) but I can't have a function that executes any IO. For example, it is not possible to write a function my_read_file that could work like this: my_data = my_read_file(my_file.txt) Correct? Otherwise this would be a function that is not referentially transparent. Cheers, Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On 12/21/05, Wolfgang Jeltsch [EMAIL PROTECTED] wrote: Am Mittwoch, 21. Dezember 2005 11:48 schrieb Robin Green: [...] If people want Haskell to be treated as a practical language, not just something for doing academic teaching and research with, it should be taught as a practical language - which means that things like IO and space/time usage come to the forefront. So programming is only practical if it's deals with a lot of I/O? This is wrong, in my opinion. Take a compiler. The only I/O it does is some simple file I/O. The important part of the compiler doesn't deal with I/O at all. I'm pretty sure that's not what he was saying. But a practical application need IO. I'm not saying that only applications doing *lots* of IO should be considered practical, I'm saying that any real-world stand-alone application needs *some* IO. Beginners know that too. In fact, they often think that practical applications need far more IO than they really do! So to insinuate even slightly that Haskell is bad at IO by avoiding it for two thirds of a book, is really going to inforce the idea that Haskell isn't a practical language for practical applications. It's easily remedied by teaching them a little IO up front (to show them it's not scary), and then leaving it alone for a while, having a more thorugough treatment of it later on. /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
Wolfgang Jeltsch writes: - Original Message - Am Mittwoch, 21. Dezember 2005 13:15 schrieb Creighton Hogg: [...] Monads, I believe, can be just thought of as containers for state. I would say that you are talking especially about the I/O monad here. A monad as such is a rather general concept like a group is in algebra. While this is correct, I'm afraid that for most of us it is a flavorless answer. I wish I had the mathematical mind that made the word group in this context instantly intuitively recognizable, but I don't. I think Phil Wadler said it best when he said that a monad is a *computation*. If a function is a mapping between input and output values, a computation is both an invocation of a function and the provision of values --- which can include state, ordering, and many other things. Of course, I'm a Phil Wadler fan anyway. The important point of the integration of imperative programming in Haskell is not that it's done using monads. The point is that you have a specific type (IO) whose values are descriptions of I/O actions, and some primitive operations on IO values. The IO type together with two of these primitive operations forms a monad but this is secondary in my opinion. Yes and no. It is important for me, at least, to continue to grasp that IO is just not a functional thing --- it is not captured intuitively in a function. Rather, it is a computation --- IO doesn't make sense until it executes in an environment which it can effect. This is why we capture IO (as well as other computational concepts) in monads, and why (again IMHO) mondadic IO is so much more effective and intuitive than continuation style IO or stream based IO ever was. Dave Barton ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Sebastian Sylvan wrote: Well, I certainly disagree there. I'm not advocating going into a full-blown explanation of monads, just enough to actually be able to write a real stand-alone program after the first chapter. They only need to know that do-notation is for sequencing computations, and (-) is for binding a name to the result of a computation. That's it! As a newbie... I agree that a newbie should be able to write this fairly early on: main = do x - getLine() putStrLn (The answer is ++ show(fib(read(x Now, you just said do-notation is for sequencing computations. Would it be fair to say that do-blocks are imperative blocks in an otherwise functional program? You could spend the next ten chapters with coding examples that are not very IO-heavy, and lead with a good example of doing as much as possible in the pure world (as well as pointing out every now and then whenever a particularly good IO-separtion was achieved - to emphasize that it's good practice). When someone who has programmed before learns Haskell and gets the impression that IO is beeing left for later because it's hard they might think bah, what a rubbish language, IO in Visual Basic isn't hard at all!. I would agree with both paragraphs. Show basic IO and show that there's no need for complex IO because all the logic should be functional. Cheers, Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Sebastian Sylvan wrote: Beginners know that too. In fact, they often think that practical applications need far more IO than they really do! So to insinuate even slightly that Haskell is bad at IO by avoiding it for two thirds of a book, is really going to inforce the idea that Haskell isn't a practical language for practical applications. It's easily remedied by teaching them a little IO up front (to show them it's not scary), and then leaving it alone for a while, having a more thorugough treatment of it later on. You can show them this on the first page: main = do x - getLine() print my_program(x) And spend the next 200 pages showing them all the nifty things and purely functional things that my_program() could do and not mention monads until chapter 14. Cheers, Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
On Wed, 21 Dec 2005, Daniel Carrera wrote: Creighton Hogg wrote: x is a String, getLine has type IO String. That's what I was getting at in one of my last e-mails. Hmm... let's see if I understand: * getLine() has type IO String. * The - will convert an IO String to a plain String * So if I do x - getLine() then x has the type String. So, the - effectively ammounts to an IO a - a conversion. Yeah, pretty much. You're saying that x is the result of action getLine, and in terms of types it means you're getting the a out of m a. In another email John Hughes said that one could think of IO a as a set of instructins for obtaining a. I guess that means that IO is a sort of imperative layer that helps the purely functional code interact with the outside world. So I can have an IO bit (e.g. a do-block) that calls functions (which are purely functional code) but I can't have a function that executes any IO. For example, it is not possible to write a function my_read_file that could work like this: my_data = my_read_file(my_file.txt) Correct? Otherwise this would be a function that is not referentially transparent. Assuming I understand correctly, then you are right. = implies definition. my_data is the symbol assigned to the result of a computation, not a defined constant or function. That's at least how I think of referential transparency. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Killer pickler combinators (was Time leak)
The other thing worth noting is that by inserting a lock with a thread delay we are fooling ourselves. While the individual pickling time goes down, the threads are slowed down overall. Assuming that an external source was waiting for the unpickled packet _that_ source would get a timeout! -- http://wagerlabs.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, 2005-12-21 at 13:10 +0100, Udo Stenzel wrote: . . . tutorial. Before that, IO should be restricted to the EVA principle (Eingabe, Verarbeitung, Ausgabe == Input, Processing, Output). It was a good principle in the 60s, and it still is. Unless you want to teach people to program as they would do in Basic, that is. Don't forget that the pioneers of IPO (Input,Process,Output) quickly went to HIPO (Hierarchical IPO). My natural design style is top-down, functional decomposition, separation of concerns, all the good things. Many problems involve relatively complex mixtures of IO and processing, which I can capture fairly naturally with programs whose IO is distributed over various nodes low in a functional decomposition tree. It often feels like I'm turning a program inside-out to have the IO monad at the top with pure functional snippets called at various points in a do sequence. And if the only way to express my decomposition tree is with a tree of imperative code inside the IO monad, then I start to ask, Why am I here? I can write this in Scheme or Ocaml. Since I'm a Haskell novice, I'm well aware that I may totally misunderstand the situation. However, I hadn't seen anything in tutorials that would lead me to think so. That said, one of the great effects of these recent threads is that they've alerted me to the fact that apparently the available tutorial information has expanded and been improved since last I looked. So I think I shall now go do some deep browsing; thanks for the links. -- Bill Wood PS: While looking over my post it occurred to me that the issue is at least as much methodological as it is linguistic. So I ask: Does Haskell stand far enough apart from other programming languages to warrant adapting standard methodological principles to it? Is there an identifiable Haskell Way? -- bw ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: When to teach IO (was Tutorial uploaded)
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Robin Green No, that's not what I meant at all. I meant that for *many* but not all practical programming tasks, IO is important. Games, GUI office applications, database applications, web applications, etc. Compilers are atypical in this regard. Something that is perceived as being only useful for a compilers and a few other academic-ish things isn't going to be perceived as very practically useful. -- Robin Hear, hear. Compilers, and computationally complex programs in general, are atypical. IMO, a lot of programming these days is integration work i.e. shuffling and transforming data from one system to another, or transforming data for reports, etc. Not many programmers write compilers these days :-( (apologies to the Simons, and John Meacham, and anyone else who *has* written a compiler, Haskell or otherwise...) http://www.mcs.vuw.ac.nz/~kjx/papers/nopp.pdf It's good to start with IO. Reading and writing files, parsing and printing (show and read), talking to databases, GUIs, and networking are more-or-less essential activities, and people want to know early on how to do these things. You don't have to introduce the IO monad; just tell people that we separate IO functions from pure functions with this special IO type, and, with the imperative do-notation, IO code in Haskell looks a lot like IO code in C/Java/.Net. The Really Good Stuff (real monadic programming) can come later. Perhaps there are two different worlds to consider. Teaching Haskell to tertiary students might well be better suited to a style where purely functional programming is explored in some detail before IO and monads are introduced. However, a jobbing programmer evaluating Haskell wants to know how they do the things they're used to doing in other langauges, and if they see the volume of stuff that must be covered before topics like IO, GUIs, and networking, they'll start to look elsewhere... How hard should it be to shove a window on the screen, or select some data from a database? Part of the problem is that we're not just introducing a new language, we're introducing a new paradigm. I can see that a noob would choke if you tried to ram it down their throat all at once. As a comparison, I have some .Net books in front of me, and although they also introduce the language first (declarations, choice, iteration, classes and interfaces), it's pretty trivial stuff and can be skimmed over fairly quickly, and then you quickly get into introspection (reflection), GUIs, IO, databases, and networking. Indeed, the bulk of the book covers these topics. Alistair * Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. * ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On 12/21/05, Daniel Carrera [EMAIL PROTECTED] wrote: Sebastian Sylvan wrote: Beginners know that too. In fact, they often think that practical applications need far more IO than they really do! So to insinuate even slightly that Haskell is bad at IO by avoiding it for two thirds of a book, is really going to inforce the idea that Haskell isn't a practical language for practical applications. It's easily remedied by teaching them a little IO up front (to show them it's not scary), and then leaving it alone for a while, having a more thorugough treatment of it later on. You can show them this on the first page: main = do x - getLine() print my_program(x) Well, more like main = do x - getLine print (my_program x) But we get the point! :-) -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: When to teach IO (was Tutorial uploaded)
On Wed, Dec 21, 2005 at 03:47:14PM -, Bayley, Alistair wrote: It's good to start with IO. Reading and writing files, parsing and printing (show and read), talking to databases, GUIs, and networking are more-or-less essential activities, and people want to know early on how to do these things. You don't have to introduce the IO monad; just tell people that we separate IO functions from pure functions with this special IO type, and, with the imperative do-notation, IO code in Haskell looks a lot like IO code in C/Java/.Net. The Really Good Stuff (real monadic programming) can come later. I'd just add that in my opinion its handling of IO is actually one of the *strengths* of Haskell. The primary advantage Haskell has (in my mind) is that it is strongly typed, and the monadic handling of IO is an impressive display of how much that typing can clarify one's code. I'd far rather write IO code in Haskell than in any other language. Pure code can be written in any language pretty easily (albeit more easily in a functional language), since pure code doesn't have the complexities present in IO code, and it's in handling those complexities that the type-safety of Haskell really helps. -- David Roundy http://www.darcs.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Substring replacements
From: Daniel Fischer [EMAIL PROTECTED] To: Branimir Maksimovic [EMAIL PROTECTED] CC: Bulat Ziganshin [EMAIL PROTECTED], Haskell-Cafe@haskell.org KMP is O(m) while straightforward is O(m*n). Where m is the length of the input and n is the length of the searched-for pattern, I think? Yes. But these are worst-case complexities, I believe, ordinarily, straightforward will be O(m), too. Yes, those are worst cases for both algorithms. O(m) for KMP, O(m*n) for straightforward. My test favors straightforward, in any other case KMP wins by order of magnitude. Can you give example tests? Any example that has long search pattern say (many a's followed by b ) and searched string has many partial matches (many a's). Particularly, any example which exhibits O(m*n) or close to, case for straightforward search. Greetings, Bane. _ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Am Mittwoch, 21. Dezember 2005 16:30 schrieb Daniel Carrera: [...] Would it be fair to say that do-blocks are imperative blocks in an otherwise functional program? Not really. do expressions are (normally) equivalent to expressions containing applications of (=) and/or (). If the monad you use is IO then a do expression isn't really an imperative block but an expression whose value is a *description* of an imperative block. If the monad you use is not IO then a do expression may have nothing to do with imperative code at all. [...] Cheers, Daniel. Best wishes, Wolfgang ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, 21 Dec 2005, Udo Stenzel wrote: [... re pitfalls of IO for the beginner ] Here's another one: I've heard a fellow claim, Haskell is basically unsuitable to implement a compiler, because Haskell is weak at IO and everything needs IO, the lexer, the preprocessor, the parser, the pretty-printer, ... Can you imagine what convoluted mess he would write if he learned IO first? I wouldn't be too worried. If these things really must be learned in some prescribed order, then we're all doomed - who here learned Haskell as their first programming language? Meanwhile, that fellow evidently didn't write any compiler in Haskell at all. Better a C++ program than a Haskell program that offends you? Donn Cave, [EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Killer pickler combinators (was Time leak)
From: Joel Reymont [EMAIL PROTECTED] To: Branimir Maksimovic [EMAIL PROTECTED] CC: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Killer pickler combinators (was Time leak) Date: Wed, 21 Dec 2005 14:51:42 + I'm not sure I buy this. Again, this helps: {-# NOINLINE lock #-} lock :: MVar () lock = unsafePerformIO $ newMVar () trace s = withMVar lock $ const $ putStrLn s and then in read_ cmd - read h trace trace is called _after_ all the timings in read so it should not affect the timings. It does not affects timings directly , but indirectly. You have putStrLn which performs some work and that is point of serialization. Try no op instead of putStrLn and you should get timeouts again. i'm sure you'll get even better operation timings if you lock around whole timing operation instead. This will be valid only for single CPU only. In this way you actually get same throughoutput, with or without lock. It' just you have to measure cummulative reads/sec which will be same with/without lock for single CPU/worker thread. Again, only way to improve performance is to use more then one CPU/worker thread. Greetings, Bane. You could basically say that the lock is at the end of read, after all the unpickling has been done. The other interesting thing is that replacing trace with delay _ = threadDelay 1 does not solve the issue. On Dec 21, 2005, at 2:33 PM, Branimir Maksimovic wrote: In this code: do TOD time1 _ - getClockTime (kind, ix1) - unpickle puCmdType ptr ix TOD time2 _ - getClockTime (cmd', _) - unpickle (puCommand kind) ptr ix1 TOD time3 _ - getClockTime you get time multiple times. So if you lock whole operation nothing else will be executed while in this code and therefore you don;t have timeouts. But, without lock more threads you have, more time have to wait for operation to finish and therefore timeouts. -- http://wagerlabs.com/ _ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
Am Mittwoch, 21. Dezember 2005 16:28 schrieb David Barton: Wolfgang Jeltsch writes: - Original Message - Am Mittwoch, 21. Dezember 2005 13:15 schrieb Creighton Hogg: [...] Monads, I believe, can be just thought of as containers for state. I would say that you are talking especially about the I/O monad here. A monad as such is a rather general concept like a group is in algebra. While this is correct, I'm afraid that for most of us it is a flavorless answer. I wish I had the mathematical mind that made the word group in this context instantly intuitively recognizable, but I don't. The point is that the concept of a monad is a rather abstract one. Maybe we should take vector spaces instead of groups. A vector space is just a set together with two operations, namely vector addition and scalar multiplication whereby the operations have to fulfill a couple of laws. One law, for example, would be that vector addition is commutative. The point is that this vector space concept is very general. There are a lot of concrete vector spaces which all fit that general idea. For example, R^2 together with the commonly defined vector addition and scalar multiplication is a vector space. But there are many others, lots of which seem to have nothing to do with R^2 and its operations from the first sight. So we have a general concept vector space and a lot of concrete vector spaces. Now, monad is a general concept like vector space. In Haskell terms a monad is a type of kind * - * (i.e., a type which needs to be applied to one type parameter in order to be able to be used as a type of expressions) together with operations (=) and return whereby (=) and return have to have specific types and have to fulfill certain laws. IO together with its (=) and return is an example of a concrete monad. [] together with concatMap and \x - [x] is another one. This may seem very surprising at first (What do lists have to do with I/O computations?) but it's really so. I think Phil Wadler said it best when he said that a monad is a *computation*. No, a value of type IO something is a computation. The type IO plus (=) plus return is a monad. So is [] plus concatMap plus \x - [x]. [...] Dave Barton Best wishes, Wolfgang ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Fwd: Monads and pedagogy (Functions with side-effects?)
Oops...meant to send this to the list, too. --- Greg Woodhouse [EMAIL PROTECTED] wrote: Date: Wed, 21 Dec 2005 09:42:44 -0800 (PST) From: Greg Woodhouse [EMAIL PROTECTED] Subject: Monads and pedagogy (Functions with side-effects?) To: David Barton [EMAIL PROTECTED] --- David Barton [EMAIL PROTECTED] wrote: Wolfgang Jeltsch writes: - Original Message - Am Mittwoch, 21. Dezember 2005 13:15 schrieb Creighton Hogg: [...] Monads, I believe, can be just thought of as containers for state. I would say that you are talking especially about the I/O monad here. A monad as such is a rather general concept like a group is in algebra. While this is correct, I'm afraid that for most of us it is a flavorless answer. I wish I had the mathematical mind that made the word group in this context instantly intuitively recognizable, but I don't. Groups are actually relatively intuitive structures, representing (no pun intended) the symmetries of some type of object. So, in teaching group theory it is easy to immediately provide a number of easy to grasp examples: the symmetric group (any kind of rearrangement), the cyclic group (cyclic permutation), dihedral group (geometric symmetries of a square), SL(n, R) (area preserving linear transformations), SO(n, R) (transformation preserving angles), Isom(M) (all geomteric motions of an object so that in the end it occupies the same space without any stretching or other deformation), etc., etc. Rings are a little more tricky, but R[x] (polynomials over R) is the universal example, with homomorphic images like Z[i] just being polynomials in i where you reduce according to i^2 = -1, and so on. Matrices over a ring give you the prototypical example of a module. I could go on, but the point is that in abstract algebra it is usually easy to provide simple intuitive examples of the structures illustrating most of the basic properties of the category. (Okay, okay, topoi and coherent sheaves may be an exception! But even then, analytic functions go a long way.) With monads, it is not hard to give a formal definition, just as is the case with groups, but much harder (for me, anyway) to find a simple intuitive set of examples that capture the essence of monads in such a way that the definition is obvious. Think about it: If groups are just symmetries, then doing nothing is clearly a symmetry (1), doing nothing before or after a symmetry doesn't change anything. Undoing a symmetry gives you an inverse. Associativity is less obvious, unless you think of groups realized as permutations of a set, so that the group product just becomes function composition. === Gregory Woodhouse [EMAIL PROTECTED] Interaction is the mind-body problem of computing. --Philip L. Wadler ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] comprehension generators from IO [a]'s ?
Hello Steve, Monday, December 19, 2005, 10:42:19 PM, you wrote: SH What I'm after is something like: SH -- (psuedo-code) SH [(b,c,d) | SHb - getDirectoryContents a_dir, SHc - getDirectoryContents (a_dir ++ / ++ b), SHd - getDirectoryContents (a_dir ++ / ++ b ++ / ++ c) ], this can't work because IO itself a monad, so IO [a] is two monads, and you can iterate only over external one, which is IO. instead: let foreach = flip mapM list - foreach (getDirectoryContents a_dir) $ \b - foreach (getDirectoryContents (a_dir ++ / ++ b)) $ \c - foreach (getDirectoryContents (a_dir ++ / ++ b ++ / ++ c)) $ \d - return (b,c,d) return $ concatMap $ concatMap list SH This function isn't so clear at a glance, and yet what it's doing SH seems like a pretty common thing to want to do: are there any library SH functions for monads (or IO in particular) that make this sort of thing SH easier, or should I to try and write my own function? Looks not too SH difficult to write but I think I might miss something important if I didn't ask SH first... How would you do it? if you just need to find all files recursively - use library http://hackage.haskell.org/packages/FilePath-0.1.0.tgz to manipulate filenames and function `doesDirectoryExist` to check that it is a directory. don't forget that `getDirectoryContents` returns list what contains names . and .. -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
--- Wolfgang Jeltsch [EMAIL PROTECTED] wrote: I think Phil Wadler said it best when he said that a monad is a *computation*. To be honest, I'm still struggling with the monad concept myself. Oh sure, I can read the definition and it makes sense. But I'm still missing that aha! moment when it all comes together. No, a value of type IO something is a computation. The type IO plus (=) plus return is a monad. So is [] plus concatMap plus \x - [x]. This may be totally off-base, but when I read this, it occured to me that all I/O is basically a computation made to appear as if it is something your program does. You (or, rather the processor) don't execute instructions to write Hello in same way as, say, adding 2 and 2. Rather, you add writing this string to a to do list and wait for a driver to respond to an interrupt, pick up the request(s), and carry it (them) out when control passes back the kernel. === Gregory Woodhouse [EMAIL PROTECTED] Interaction is the mind-body problem of computing. --Philip L. Wadler ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Problems with square root...
Hey, The sqrt function is not doing what I want. This is what I want: round sqrt(2) The problem is that sqrt() returns a Floating value and round wants a ReacFrac: --//-- *Main round sqrt(2) interactive:1:0: No instances for (RealFrac (a - a), Integral (t - a1)) arising from use of `round' at interactive:1:0-4 Probable fix: add an instance declaration for (RealFrac (a - a), Integral (t - a1)) In the definition of `it': it = round sqrt (2) *Main --//-- I'm trying to figure out how to turn a Float into a RealFrac so I can pass it to 'round'. Any ideas? Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
Donn Cave wrote: Meanwhile, that fellow evidently didn't write any compiler in Haskell at all. Better a C++ program than a Haskell program that offends you? Oh no, he actually wrote something disgusting built mostly out of regexes in Perl. I don't think it even works, and I don't think I could have convinced him to Do The Right Thing in whatever language. But that's besides the point. The conviction that a parser or lexer or prettyprinter means IO is simply wrong, and imho a tutorial should show how much is purely functionally possible before introducing control flow, mutable variables and all the other ugliness. It's more productive this way. Udo. -- Slous' Contention: If you do a job too well, you'll get stuck with it. signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with square root...
Daniel Carrera wrote: Hey, The sqrt function is not doing what I want. This is what I want: round sqrt(2) Sigh... never fails. Spend an hour trying to solve a problem, and a minute after you write to the list you find the solution. I need brackets around sqrt. I'm surprised though. I don't understand why it dosn't work without brackets. Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with square root...
On 12/21/05, Daniel Carrera [EMAIL PROTECTED] wrote: round sqrt(2) I don't understand why it dosn't work without brackets. Function application is left associative in Haskell. -- regards, radu http://rgrig.blogspot.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with square root...
On 2005-12-21 at 18:10GMT Daniel Carrera wrote: Daniel Carrera wrote: Hey, The sqrt function is not doing what I want. This is what I want: round sqrt(2) Sigh... never fails. Spend an hour trying to solve a problem, and a minute after you write to the list you find the solution. I need brackets around sqrt. I'm surprised though. I don't understand why it dosn't work without brackets. Elementary syntax. Function application needs no parentheses and associates left, so sqrt 2 is fine, and what you wrote means (round sqrt) 2 whereas what you want is round (sqrt 2) -- Jón Fairbairn Jon.Fairbairn at cl.cam.ac.uk ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with square root...
Sigh... never fails. Spend an hour trying to solve a problem, and a minute after you write to the list you find the solution. I need brackets around sqrt. I'm surprised though. I don't understand why it dosn't work without brackets. because x y z parses as (x y) z, so round sqrt 2 parses as (round sqrt) 2 and round sqrt doesn't make sense. x(y) doesn't mean necessarily apply y to x as it does in C. parens only are used as they are in math to separate stuff. -- Hal Daume III | [EMAIL PROTECTED] Arrest this man, he talks in maths. | www.isi.edu/~hdaume ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with square root...
Radu Grigore wrote: I don't understand why it dosn't work without brackets. Function application is left associative in Haskell. Ah. I implicitly assumed right-association (it works in Perl ;) ) Thanks. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with square root...
On Wed, Dec 21, 2005 at 06:10:56PM +, Daniel Carrera wrote: Daniel Carrera wrote: Hey, The sqrt function is not doing what I want. This is what I want: round sqrt(2) Sigh... never fails. Spend an hour trying to solve a problem, and a minute after you write to the list you find the solution. I need brackets around sqrt. I'm surprised though. I don't understand why it dosn't work without brackets. In Haskell parentheses are not part of function call syntax, unlike many languages like C, Pascal or Java. The role of parentheses in expressions is only for grouping and disambiguation. What you typed is actually equivalent to round sqrt 2 which in turn is equivalent to ((round sqrt) 2) because function application is left-associative. Best regards Tomasz -- I am searching for a programmer who is good at least in some of [Haskell, ML, C++, Linux, FreeBSD, math] for work in Warsaw, Poland ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: First steps in Haskell
Hello Alistair, Tuesday, December 20, 2005, 1:13:50 PM, you wrote: BA And there's this interesting site, which demos a interpreter running in BA your browser it's a neat idea! I/O-stripped version of hugs can be runned in such way btw, i send to newcomers the following recommendations: i can recommend you two books for beginners: Gentle inroduction to Haskell http://www.haskell.org/tutorial/haskell-98-tutorial-html.tar.gz Yet Another Haskell Tutorial by Hal Daume III http://www.isi.edu/~hdaume/htut/tutorial.pdf and book + PowerPoint tutorial by Graham Hutton: http://www.cs.nott.ac.uk/~gmh/preview.pdf http://www.cs.nott.ac.uk/~gmh/mgs-appsem1.ppt http://www.cs.nott.ac.uk/~gmh/mgs-appsem2.ppt http://www.cs.nott.ac.uk/~gmh/mgs-appsem3.ppt http://www.cs.nott.ac.uk/~gmh/mgs-appsem-exam.pdf http://www.cs.nott.ac.uk/~gmh/countdown.pdf btw, in the another haskell tutorial we can read: There have been many books and tutorials written about Haskell; for a (nearly) complete list, visit the http://haskell.org/bookshelf (Haskell Bookshelf) at the Haskell homepage. A brief survey of the tutorials available yields: - A Gentle Introduction to Haskell is an introduction to Haskell, given that the reader is familiar with functional programming en large. - Haskell Companion is a short reference of common concepts and definitions. - Online Haskell Course is a short course (in German) for beginning with Haskell. - Two Dozen Short Lessons in Haskell is the draft of an excellent textbook that emphasizes user involvement. - Haskell Tutorial is based on a course given at the 3rd International Summer School on Advanced Functional Programming. - Haskell for Miranda Programmers assumes knowledge of the language Miranda. - PLEAC-Haskell is a tutorial in the style of the Perl Cookbook. to this list, link to page A Tour of the Haskell Prelude can also be added -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Battling time leaks
Hello Joel, Tuesday, December 20, 2005, 3:38:17 PM, you wrote: It looks like I successfully squashed my time leaks and moving my serialization to Ptr Word8 got me as close to the metal as possible. I'm still getting wierd results, though, and they look like a time leak. ORANGE ALERT: 0s, 6s, SrvServerInfo can you say what it exactly means? we are not mastered in your code. some common explanation like my program takes 6 seconds to deserialize 50kb of data on Pentium4/3ghz will be more understabdable if your current problem is deserialization speed, i can give you my own library. it now runs about 500kb/sec on 1ghz processor -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Tutorial uploaded
Some example for writing a text the IO oriented way: do putStrLn bla replicateM 5 (putStrLn blub) putStrLn end whereas the lazy way is putStr (unlines ([bla] ++ replicate 5 blub ++ [end])) Um, maybe it's just me, but I think the first program is far superior to the second one. The last thing you want your I/O code to be is lazy. You want the exact opposite: you want it to be as strict as possible. Not only does the second version waste a lot of CPU time and memory for pointlessly constructing a lazily evaluated list nobody ever needs, it will also explode into your face the moment you use that approach to write any non-trivial number of bytes. Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Battling time leaks
On Dec 20, 2005, at 1:38 PM, Bulat Ziganshin wrote: can you say what it exactly means? we are not mastered in your code. some common explanation like my program takes 6 seconds to deserialize 50kb of data on Pentium4/3ghz will be more understabdable That's why I posted the code at http://wagerlabs.com/timeleak.tgz The alerts are issued when the time of unstuffing exceeds 3 seconds. if your current problem is deserialization speed, i can give you my own library. it now runs about 500kb/sec on 1ghz processor My issue is that I 1) have about 250 records and 2) my wire format is different from the Haskell representation. Everything arrives to me little-endian, for example. It looks like pickling is the bottleneck so I'm converting all the structures to Storable :(. In the meantime, I'm looking for suggestions. Einar offered BinSer which lets me use a single spec for the record format, conversions included. See http://cs.helsinki.fi/u/ekarttun/ haskell/test.hs. I still can't figure out how I would go from a :+: b to Foo a b, though. Thanks, Joel -- http://wagerlabs.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, Dec 21, 2005 at 07:35:28PM +0100, Peter Simons wrote: Some example for writing a text the IO oriented way: do putStrLn bla replicateM 5 (putStrLn blub) putStrLn end whereas the lazy way is putStr (unlines ([bla] ++ replicate 5 blub ++ [end])) Um, maybe it's just me, but I think the first program is far superior to the second one. The last thing you want your I/O code to be is lazy. You want the exact opposite: you want it to be as strict as possible. Not only does the second version waste a lot of CPU time and memory for pointlessly constructing a lazily evaluated list nobody ever needs, it will also explode into your face the moment you use that approach to write any non-trivial number of bytes. Isn't it just the usual elegance/efficiency trade-off? Personally, I would prefer the first version, unless it was not efficient enought. Actually this example is a bit too simple to show the benefits and problems of both approaches. Consider using a pretty printing library vs doing the same thing as a sequence of putStr's. Best regards Tomasz -- I am searching for a programmer who is good at least in some of [Haskell, ML, C++, Linux, FreeBSD, math] for work in Warsaw, Poland ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with square root...
nitpicky detail: () - Parenthesis {} - Braces [] - Brackets Sorry to be pedantic, but using the wrong terminology confuses me and I'm sure others as well. On 12/21/05, Daniel Carrera [EMAIL PROTECTED] wrote: Daniel Carrera wrote: Hey, The sqrt function is not doing what I want. This is what I want: round sqrt(2) Sigh... never fails. Spend an hour trying to solve a problem, and a minute after you write to the list you find the solution. I need brackets around sqrt. I'm surprised though. I don't understand why it dosn't work without brackets. Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- 50% of marriages today end in divorce, the other 50% end in death. Which would you rather have? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, 21 Dec 2005, Peter Simons wrote: Some example for writing a text the IO oriented way: do putStrLn bla replicateM 5 (putStrLn blub) putStrLn end whereas the lazy way is putStr (unlines ([bla] ++ replicate 5 blub ++ [end])) Um, maybe it's just me, but I think the first program is far superior to the second one. The last thing you want your I/O code to be is lazy. You want the exact opposite: you want it to be as strict as possible. Not only does the second version waste a lot of CPU time and memory for pointlessly constructing a lazily evaluated list nobody ever needs, it will also explode into your face the moment you use that approach to write any non-trivial number of bytes. Surely the actual explosion comes about because PutStr forces the lot at once? If PutStr were to evaluate a character at a time, the laziness would be slow and spew a lot of garbage to collect but not hang on to as much space as you suggest. Not to say that the strict solution isn't still more efficient, of course. -- [EMAIL PROTECTED] The task of the academic is not to scale great intellectual mountains, but to flatten them. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with square root...
MG () - Parenthesis MG {} - Braces MG [] - Brackets MG Sorry to be pedantic, but using the wrong terminology confuses me and MG I'm sure others as well. This is true for Haskell, but Daniel is correct if he is calling () Brackets because they are, in British English, right? (Just like '.' is a 'period' in US, but it is a 'full stop' in UK.). Of course, English /= Haskell so in Haskell I guess they are called Parenthesized Expressions (in the Haskell report http://www.haskell.org/onlinereport/exps.html). To be extra pedantic, I would call {} Curly Braces (or Curly Brackets, or squiggly brackets, or squiggles, or ... just use layout and whitespace!) and I would call [] Square Brackets. Then no one gets confused. Cheerio, Jared P.S. IANAA = I am an American, so I could very well be wrong about British English! On 12/21/05, Daniel Carrera [EMAIL PROTECTED] wrote: Daniel Carrera wrote: Hey, The sqrt function is not doing what I want. This is what I want: round sqrt(2) Sigh... never fails. Spend an hour trying to solve a problem, and a minute after you write to the list you find the solution. I need brackets around sqrt. I'm surprised though. I don't understand why it dosn't work without brackets. Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- 50% of marriages today end in divorce, the other 50% end in death. Which would you rather have? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- [EMAIL PROTECTED] http://www.updike.org/~jared/ reverse )-: ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions with side-effects?
Am Mittwoch, 21. Dezember 2005 19:02 schrieben Sie: [...] You (or, rather the processor) don't execute instructions to write Hello in same way as, say, adding 2 and 2. Exactly! Rather, you add writing this string to a to do list and wait for a driver to respond to an interrupt, pick up the request(s), and carry it (them) out when control passes back the kernel. I don't completely understand what you mean but I think it goes into the right direction. We can illustrate the process of executing a Haskell program as follows. We have a evaluation machine and a execution machine. The former evaluates expressions, the latter executes I/O actions. When the program is started, the execution machine wants to execute the actions from the main to do list. In order to be able to do so, it asks the evaluation machine to start evaluating main. For each entry on the to do list, main is evaluated as far as it's necessary to provide the execution machine with the entry. Of course, evaluating main may result in evaluating other expressions. The point is that the evaluation machine does never execute any I/O actions while the execution machine is unable to do any evaluation but needs to be feeded by the evaluation machine. Best wishes, Wolfgang ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: problems with square roots...
From: Daniel Carrera [EMAIL PROTECTED] Hey, The sqrt function is not doing what I want. This is what I want: round sqrt(2) --- Daniel, A lot of Haskell folks like to avoid parentheses as much as possible, and there's a really convenient way to do this. There is a Prelude function ($) f x = f x which is right-associative, so you can write round $ sqrt x == round (sqrt x) This becomes really convenient when multiple application is involved: print $ round $ sqrt x == print (round (sqrt x)) -Chad ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: problems with square roots...
On Wed, 21 Dec 2005, Scherrer, Chad wrote: From: Daniel Carrera [EMAIL PROTECTED] Hey, The sqrt function is not doing what I want. This is what I want: round sqrt(2) --- Daniel, A lot of Haskell folks like to avoid parentheses as much as possible, and there's a really convenient way to do this. There is a Prelude function ($) f x = f x which is right-associative, so you can write round $ sqrt x == round (sqrt x) This becomes really convenient when multiple application is involved: print $ round $ sqrt x == print (round (sqrt x)) Doesn't it sometimes feel like the $ operator is Haskell's way of saying We're not with those Lisp guys, seriously? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wednesday 21 December 2005 18:48, Udo Stenzel wrote: Donn Cave wrote: Meanwhile, that fellow evidently didn't write any compiler in Haskell at all. Better a C++ program than a Haskell program that offends you? Oh no, he actually wrote something disgusting built mostly out of regexes in Perl. I don't think it even works, and I don't think I could have convinced him to Do The Right Thing in whatever language. But that's besides the point. The conviction that a parser or lexer or prettyprinter means IO is simply wrong, and imho a tutorial should show how much is purely functionally possible before introducing control flow, mutable variables and all the other ugliness. It's more productive this way. This is a red herring IMO. A good tutorial on Haskell can mention and explain how to do IO in the first chapter and /still/ show clearly and convincing how to do most of the real work in an elegant, purely functional style. It could even contain a 'bad example' where IO is used unnecessarily and compare it to the 'good' functional version. It is not a good idea to treat beginner's in Haskell as little children who must be protected from the bad world of IO as long as possible. (FWIW, it can be argued that this isn't even a good attitude toward little children.) Especially since most Haskell newcomers will have a background in imperative programming, as someone esle already mentioned. Of course, /precise/ explanation of the IO monad must be postponed to a later chapter, and surely only /after/ introducing monads in general and giving some non-IO examples. I would also argue that the word 'category theory' should /not/ appear in the main text of a tutorial (a small footnote might be acceptable, as well as a reference in a late chapter named 'further reading'). Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Killer pickler combinators (was Time leak)
Well, yes. I think that part of the problem you're having is that the threads compete very highly, and some eventually get ignored for longer than the timeouts. The reason why the (withMVar lock $ const $ putStrLn s) helped in the first place was not so much because of any evaluation of s (we tested that assumption), but rather because during the time that withMVar is active in one thread, any other threads can't pass that same point. So a bunch of the threads which were stealing too much of the time before, now end up blocking, which reduces the competition so the other threads which were being ignored by the scheduler can get some work done. Your problem is partly in the fact that the pickler/unpickler is a bit slow for the workload/machine you have it on, and partly in the fact that it's hard to get the processes to advance smoothly. (The pickling/unpickling doesn't really take very long in any one thread, but if the thread isn't scheduled for a long time in the first place...) A bit of locking is sort of what you want for that. Unfortunately, the way we have it here still affords no guarantees, it just serves as a mechanism to help keep things from getting too bad. It's unclear to me that you really don't want any kind of locking. I think that you might do quite well to decide which threads get to run yourself at least to some extent. After all, you know more about their priorities and how long they have to complete their tasks than the GHC scheduler does. - Cale On 21/12/05, Joel Reymont [EMAIL PROTECTED] wrote: The other thing worth noting is that by inserting a lock with a thread delay we are fooling ourselves. While the individual pickling time goes down, the threads are slowed down overall. Assuming that an external source was waiting for the unpickled packet _that_ source would get a timeout! -- http://wagerlabs.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Killer pickler combinators (was Time leak)
I don't want any kind of locking, true. I need all bots to respond in time otherwise the poker server will sit them out. Eliminating the timeout on pickling does not eliminate the timeout overall, it just passes it to a different place. One thread will go through serialization quickly but it will be too late by the time it sends a response to the server since it waited a few seconds for the chance to have a go at serialization. I'm trying to build 6.5 right now (having trouble, you might have guessed ;)) and will positively study the scheduler. I do not believe thread priorities are supported in GHC, though. I had a thought about using continuations but then I would also have to do selects on a few thousand file descriptors myself. Then I would have to decide which continuation to run based on priorities. I might as well patch the GHC scheduler to do what I need. Alternatively, I can just throw in the towel and rewrite the app in Erlang. I haven't made a firm decision yet, I think I will make my records storable first as you can't get any closer to the metal. If that does not work then I will just give up. I do have other apps to write in Haskell but it will be a pity if this one does not work out. Thanks, Joel On Dec 21, 2005, at 9:12 PM, Cale Gibbard wrote: Unfortunately, the way we have it here still affords no guarantees, it just serves as a mechanism to help keep things from getting too bad. It's unclear to me that you really don't want any kind of locking. I think that you might do quite well to decide which threads get to run yourself at least to some extent. After all, you know more about their priorities and how long they have to complete their tasks than the GHC scheduler does. -- http://wagerlabs.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wed, Dec 21, 2005 at 09:30:14PM +, Philippa Cowderoy wrote: On Wed, 21 Dec 2005, Tomasz Zielonka wrote: I don't know how it's done, but when you compile it with 'ghc -O2', the program runs in constant space. Unfortunately with Hugs and GHCi it grows. The live set, or just the heap? It depends on what you mean by live set. If it's the conservative approximation as used by GC (reachability from root set), then yes, because it more or less equals heap. If you mean the set of nodes that will be referenced by program in the future, then probably no. You mean the latter, right? Best regards Tomasz -- I am searching for a programmer who is good at least in some of [Haskell, ML, C++, Linux, FreeBSD, math] for work in Warsaw, Poland ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On 21/12/05, Tomasz Zielonka [EMAIL PROTECTED] wrote: On Wed, Dec 21, 2005 at 07:13:07PM +, Philippa Cowderoy wrote: Try running putStrLn (unlines (repeat hello!)) You may be surprised ;-) Or not ;-) But yes, I should've checked and my comments on how that'll behave stand. It would be nice to think something clever could happen regarding memory management as well, but I'm familiar enough with GCed systems by now to be somewhat wary of cleverness. I don't know how it's done, but when you compile it with 'ghc -O2', the program runs in constant space. Unfortunately with Hugs and GHCi it grows. It really shouldn't grow at all, and at least in my short tests in ghci and hugs, it doesn't grow for me. The putStrLn won't force any more of the string than it wants to print at any moment, and afterward, that part of the string is garbage, and should get collected right away. There are two ways to make a Haskell program more efficient: Make it stricter, or make it lazier. What do I mean by the latter? Simply that if you can design each part of your program (as much as possible) to be able to output something only given a small prefix of its input, then you'll often see some really nice efficiency. The pipeline scheduler which I wrote for a summer job made heavy use of this fact, and at a few points in the design/coding, I made ridiculously large performance gains in both memory consumption and runtime simply by making sure that lists and other structures were lazily produced. In the end, the result was a (combinatorially large) list of all the possible schedules for the given input code, in order of algorithm greediness. Taking the head of the list was essentially running the greedy algorithm, but if the greedy solution, say, couldn't be register allocated, the next item in the list could be observed, which would backtrack a bit and find another. In fact, the entire algorithm was designed this way. That's essentially what the list monad gives you, after all. Leaning on laziness can result in very elegant generative algorithms which run quite quickly. Strictness is really only desired when you are trying to collapse something large down into a small summary. That's what things like foldl' are for. - Cale ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Killer pickler combinators (was Time leak)
On 12/21/05, Joel Reymont [EMAIL PROTECTED] wrote: I don't want any kind of locking, true. I need all bots to respond in time otherwise the poker server will sit them out. Eliminating the timeout on pickling does not eliminate the timeout overall, it just passes it to a different place. One thread will go through serialization quickly but it will be too late by the time it sends a response to the server since it waited a few seconds for the chance to have a go at serialization. I'm trying to build 6.5 right now (having trouble, you might have guessed ;)) and will positively study the scheduler. I do not believe thread priorities are supported in GHC, though. I had a thought about using continuations but then I would also have to do selects on a few thousand file descriptors myself. Then I would have to decide which continuation to run based on priorities. I might as well patch the GHC scheduler to do what I need. Alternatively, I can just throw in the towel and rewrite the app in Erlang. I haven't made a firm decision yet, I think I will make my records storable first as you can't get any closer to the metal. If that does not work then I will just give up. I do have other apps to write in Haskell but it will be a pity if this one does not work out. I've only skimmed through this, so I may miss the point, but it sounds like a latency vs bandwidth discussion. Let's say you push through 5000 requests in one second (i.e you start 5000 processes and then exactly one second later all 5000 complete simultaneously). Now 5 in ten seconds is actually the exact same throughput, but if your timeout is three seconds, then you'll get problems. So your problem is that you only do a tiny bit of work for each processess over and over, think of the scheduler just looping through the processess giving it a tiny slice of time, over and over and over. It may take ten seconds for any individual process to complete, but the full throughput is still the same. When you increase the number of processes you won't see the additional processes timeout, but ALL processess (or at least many of them). My suggestion is this: Find out how many processes can be serviced at one time without getting timed out (i.e. find a good compromise between latency and bandwidth), then wrap up the computaitons in a semaphore containing exactly that many resources. I think you probably want this amount to be somwehere around the number of actual CPU cores you have. Having a process' computation wait for 99% of the timeout out to start and then complete it in the final 1% is no worse then having it slowly compute its result for the duration of the timeout. The difference is that if you run out of CPU juice, only some of the processess get hurt (they timout before they start), instead of all of them (the time it takes to compute each of them is more than the timeout because the CPU is spread too thin). /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wednesday 21 December 2005 12:17, Daniel Carrera wrote: Robin Green wrote: Whilst localising IO to a small part of the program is generally a good idea, beginners should not be scared off by the thought that IO in Haskell is so hard it has to be covered on page 94. This is not the case. It should be introduced on page 1. As a newbie... I'll agree with Robin. I /did/ think that IO in Haskell was probably very difficult because it's covered in page 94. I skimmed through YAHT and IO is covered wyyy deep into the document. I haven't read that section yet, but there is a lot of content and to me it looked like it must be something difficult. I guess/hope that when I get around to reading it I'll find out that it's not as scary as it looks. Rest assured it is dead simple. Really. I would even argue that it is a lot simpler than in many other languages. The only thing that is strange for beginners is that you cannot /do/ IO from inside a function (because functions in Haskell are pure, period). However you can easily /construct IO-performing actions/ inside functions, since such actions are ordinary (first-class) /data values/. That's what monadic IO is about. IO-actions (=procedures?) are data and can be manipulated like other ordinary data. However, since IO is necessarily an /abstract/ data type, data construction is limited to what's offered by the public interface (which is essentially the type class 'Monad', plus all the 'primitive' actions, i.e. putChar, getChar, openFile, ...). One of the funny aspects of IO in Haskell is that it tends to look like perfectly ordinary imperative programming. That is what the do-Notation (including - 'assignment') is about. Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
As a newbie... I'll agree with Robin. I /did/ think that IO in Haskell was probably very difficult because it's covered in page 94. I skimmed through YAHT and IO is covered wyyy deep into the document. I haven't read that section yet, but there is a lot of content and to me it looked like it must be something difficult. I guess/hope that when I get around to reading it I'll find out that it's not as scary as it looks. Rest assured it is dead simple. Really. I would even argue that it is a lot simpler than in many other languages. I agree. It's on page 31 in YAHT, and 1-11 are getting started with Hugs and so on. One of the whole points of YAHT is to introduce it early. -- Hal Daume III | [EMAIL PROTECTED] Arrest this man, he talks in maths. | www.isi.edu/~hdaume ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problems with square root...
Mark Goldman wrote: nitpicky detail: () - Parenthesis {} - Braces [] - Brackets Sorry to be pedantic, but using the wrong terminology confuses me and I'm sure others as well. Being pedantic can be fun :) The Macquarie Dictionary, which is the official dictionary in Australia, says that () are brackets. It says that they are also called parentheses or a round bracket, if you need to distinguish between them and square brackets [], curly brackets {}, or angle brackets , and the definition for parenthesis is the upright brackets (). Also, I believe, UK English (and International English) uses the term brackets that way, but I'd have to check online to make sure; I don't have a UK dictionary on me right this minute. Cheers, Daniel. -- /\/`) http://oooauthors.org /\/_/ http://opendocumentfellowship.org /\/_/ \/_/I am not over-weight, I am under-tall. / ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
noise The truth is, Haskell friggen rocks at IO compared to imperative languages. We are all spoiled and see IO in haskell as ugly because we have been exposed to the pure functional goodness of the rest of haskell. but teaching haskell as a better impertive language than imperative ones from the getgo seems like a very good approach for bringing people over. Just the idea that you can write things like mapM and replicateM is enough to blow the mind of many impertive programmers. They don't need to be forced to learn the pure functional side, they will eventually learn to do so on their own because it is so darn nice. You can't not start with IO for people who already know how to program, if you are teaching someone programming for the very first time then starting with the pure functional side is fine. But for people that already know how to program, they are constantly thinking of everything else they have written and how they might do it in the language they are currently learning comparing and contrasting in their head. They need to have the tools to replicate what they have done with other languages right away, they don't want to know how to do the examples given in the book except insofar as they let them understand how to write the examples wiggling around in their head. /noise John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Tutorial uploaded
On Wednesday 21 December 2005 16:49, Sebastian Sylvan wrote: On 12/21/05, Daniel Carrera [EMAIL PROTECTED] wrote: Sebastian Sylvan wrote: Beginners know that too. In fact, they often think that practical applications need far more IO than they really do! So to insinuate even slightly that Haskell is bad at IO by avoiding it for two thirds of a book, is really going to inforce the idea that Haskell isn't a practical language for practical applications. It's easily remedied by teaching them a little IO up front (to show them it's not scary), and then leaving it alone for a while, having a more thorugough treatment of it later on. You can show them this on the first page: main = do x - getLine() print my_program(x) Well, more like main = do x - getLine print (my_program x) This: main = do x - getLine print (my_program x) would be correct too. (Just to make it clear that the main point was not the different layout but the parentheses: Haskell uses them only to indicate precedence, they are not required around function arguments.) Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Tutorial uploaded
Daniel Carrera wrote: As a newbie... I agree that a newbie should be able to write this fairly early on: main = do x - getLine() putStrLn (The answer is ++ show(fib(read(x I'd agree for some definition of 'early'. I'll elaborate: This entire discussion is about 'breaking a cyclic graph of conceptual dependencies'. Unfortunately, I don't think it can be done well in short amount of time. The above code snippet contains typeclasses (show, read, monadic IO, lists), syntactic sugar (do, -). When you say a 'newbie' should be able to write that early on, I'd interpret that as 'a newbie should be able to regurgitate this early on' because the next thing a newbie might want to do is try to divide the result of fib by a float and wonder why he can't do that, or try to debug his fib implementation by trying to insert a putStrLn. There are numerous ways to frustration unless the newbie is comfortable with typeclasses, monads, etc. This happens all the time when somebody is learning a new language, but it's most problematic for haskell because the breadth of knowledge (of various concept of the language) a learner has to gather before he can dive deep (formulation, compilation, execution, debugging) into an actual (even trivial) program is larger than all popular languages out there. In every language, the most powerful features make their ways into the most basic elements (as they should so that the entire language benefits, but then, lists are monads?!?!). Learners of C++ with a C background are not as much troubled by cout yadda endl; even though there is operator overloading, references and the streams class hieararchy in that statement. You can close your eyes and pretend that cout is just magic and re-visit that node when you are comfortable with classes. I don't think we can break cycles easily like that in Haskell. The mental load is very high, and with concerns about language features vs complexity even in other languages (see http://lambda-the-ultimate.org/node/view/1155) I think we are observing a new phenomenon: languages worth learning from now on will be increasingly difficult (heck, even Perl is difficult now), and we'll have to do away with 'tutorials' mostly. In fact what we have are not really tutorials (YAHT is a small book! compare that with http://www.ocaml-tutorial.org/). I think it's a tall order for a 'tutorial' to teach Haskell (which may be why we end up reading 4-5 of them). In fact Hudak's Haskell book was the first introductory language book I'd ever bought. That's why I think tutorials can have be frustrating and it takes a well edited book and . Cheers, Koray ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe