Re: [Haskell-cafe] Small question
On Sat, Aug 11, 2007 at 12:06:23AM -0400, David Menendez wrote: On 8/10/07, Andrew Coppin [EMAIL PROTECTED] wrote: My program needs to make decisions based on a pair of boolean values. Encoding both values as a single algebraic data type means I have to keep taking it apart so I can work with it. I'm not sure how much time this wastes... Incidentally, there is an argument that many (perhaps most) use of Bool should instead be custom datatypes. That is, instead of: type FooBar = (Bool, Bool) one should instead do something like data Foo = Foo | AntiFoo data Bar = Baz | Bo type FooBar = (Foo, Bar) which makes it clearer what's going on and harder to confuse the two booleans. Of course, now you have to replace \(foo, bar) - if foo then ... else ... with \(foo, bar) - if foo == Foo then ... else ... or \(foo, bar) - case foo of { Foo - ...; Bar - ... } Actually, that raises an interesting question. Is there a performance difference between if foo == Foo ... and case Foo of ...? I think JHC's case-hoisting should be able to transform the former into the latter, but does it? You don't need to go all the way to JHC[1] for this; GHC's case-of-case transformation is perfectly adequate, as GHC itself will tell you: [EMAIL PROTECTED]:/tmp$ ghc -c -ddump-simpl -O2 X.hs ... X.moo :: X.Ay - GHC.Base.Int ... X.moo = \ (x_a6D :: X.Ay) - case x_a6D of wild_Xq { X.Be - X.lit; X.Ce - X.lvl } [EMAIL PROTECTED]:/tmp$ cat X.hs module X where data Ay = Be | Ce deriving(Eq) moo x = if x == Be then 2 else (3::Int) [EMAIL PROTECTED]:/tmp$ ghc -c -ddump-simpl-stats -O2 X.hs FloatOut stats: 1 Lets floated to top level; 0 Lets floated elsewhere; from 4 Lambda groups FloatOut stats: 0 Lets floated to top level; 0 Lets floated elsewhere; from 3 Lambda groups Grand total simplifier statistics Total ticks: 46 9 PreInlineUnconditionally 11 PostInlineUnconditionally 6 UnfoldingDone 1 RuleFired 1 ==#-case 9 BetaReduction 2 CaseOfCase--- 7 KnownBranch 1 CaseMerge 11 SimplifierDone [EMAIL PROTECTED]:/tmp$ Stefan [1] GHC takes 2 hours to run a full two-stage bootstrap complete with the entire standard library. Jhc takes[2] at least 4 hours (I didn't let it finish) to compile just the Prelude. [2] 700MB working set, 384MiB primary store. This makes a difference. signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Explaining monads
On 8/10/07, Ronald Guida [EMAIL PROTECTED] wrote: Kim-Ee Yeoh wrote: Monads are undoubtedly more pervasive, and that could be because there aren't as many arrow and comonad tutorials, atomic ones or otherwise. Moreover, Comonad isn't even in the standard libraries (Hoogle returns no results for it). This is probably because no one has found a compelling use case for comonadic-style programming in Haskell. There have been some interesting papers, such as Comonadic functional attribute evaluation by Uustalu and Vene, but nothing as compelling as Wadler's Monads for functional programming. In my case, I have started to formulate my own idea for what a monad tutorial should be; I might attempt to write one, too. Be sure to read sigpfe's You could have invented monads! and the Wadler paper. http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf Most tutorials try to explain what a monad *is*, but these focus more on why they're a useful way to organize code. In my experience, being able to use a monad is more important than understanding the theory. Also, arrows are supposed to be more general than both monads and comonads. If I could just figure out what each structure (functor, monad, comonad, arrow) is doing, and compare and contrast them, then I probably will have made leaps of understanding. Arrows are more general than monads and comonads in the sense that you can create an arrow corresponding to any particular monad and comonad, but there are also arrows which correspond to neither. Functors are more general than monads and comonads simply because every monad and comonad is a functor with additional operations. (This can be obscured by the fact that the Haskell Prelude doesn't define Monad as a subclass of Functor.) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Explaining monads
ronguida: Monads are undoubtedly more pervasive, and that could be because there aren't as many arrow and comonad tutorials, atomic ones or otherwise. Moreover, Comonad isn't even in the standard libraries (Hoogle returns no results for it). When I searched for tutorials on monads, I found lots of them. In fact, I have heard that writing (yet another) monad tutorial is part of standard Haskell initiation. Regarding the available tutorials, I've collected them under each flavour here: haskell.org/haskellwiki/Blog_articles/Monads Including 42 monad tutorials, 6 arrow tutorials, and 3 comonad tutorials, and 0 on applicative functors. The source for the `standard' (only) comonad library is available from one of the sigfpe tutorials, but really should be on hackage. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] zip3, zip4 ... - zipn?
Is it possible to write a function like this: zipn n list_1 list_2 list_3 ... list_n which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable number of arguments are possible, like printf shows, so a general zipn should be possible, too. If it is possible, why there are functions like zip5 and not just zipn? -- Frank Buss, [EMAIL PROTECTED] http://www.frank-buss.de, http://www.it4-systems.de ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Explaining monads
Ronald Guida wrote: Here's my interpretation of the table: -- Structure | Subject | Action| Verb | Result +--+++-- function| a | a-b | flip ($) | b Functor | f a | a-b | $ | f b Applicative | f a | f (a-b) | flip * | f b Monad | m a | a-m b| = | m b Comonad | w a | w a-b| = | w b Arrow | a b c | a c d | | a b d -- This is the first time I've seen $. What a pleasing synonym for fmap. To maintain a similar order of parameters, I think you'd want flip $ up there. Ronald Guida wrote: -- Foo a = Foo { runFoo ::a } -- Functor State s a = State { runState :: s - (a, s) } -- Monad Context c a = Context { runContext :: (a, c) - a } -- Comonad Thing s a b = Thing { runThing :: (a, s) - (b, s) } -- Arrow??? -- I believe there is a way to see all of the above as forms of generalized application although not in the way presented here. (I thank Brian for pointing to the possibility of a unified treatment in the first place.) A point in common among your run* functions is that you can always observe the instance of type (a) in (m a :: Monad a). But monads are equipped with (return :: a - m a), not (coreturn :: m a - a). Your 2nd table is more about comonads, at least the coreturn aspect, than about whatever unity you're hoping to achieve. There's more about coreturn here: http://www.haskell.org/pipermail/haskell-cafe/2007-August/030153.html So we need to explore generalized application without being too explicit about unwrapping monads nor wrapping comonads. Why? Because being too explicit invariably locks us into one particular instantiation and the generalization goes poof! Think of all the otherwise rich and creative papers written on the IO monad and its innards. The instances of monads I've seen are in themselves too sexy (probabilistic modelling! digital circuit simulation! IO! concurrency!) that they end up overwhelming the essence of monadism pregnant within. Better to start with something boring. Like the Maybe monad. Feck heh, The essence of monadism pregnant within. Another fine title for another monad tutorial. -- View this message in context: http://www.nabble.com/Explaining-monads-tf4244948.html#a12103564 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell vs GC'd imperative languages, threading, parallelizeability (is that a word? :-D )
Spencer Janssen wrote: On Friday 10 August 2007 12:37:31 Andrew Coppin wrote: Stefan O'Rear wrote: Bool is 32 bits, but Don is using UArray. UArray is not parametric in the element type. Would be nice if it *could* somehow be parametric... but I have absolutely no idea how you'd do that. The transformation is self-evident enough to a human, but how do you explain it to a machine? Check out the various papers, slides, and talks on NDP/parrallel arrays. There's much discussion on schemes to efficiently pack data types into unboxed arrays. NDP is like Christmas! So many boxes of goodies to open... but it takes so long to come around... :-( ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] zip3, zip4 ... - zipn?
Frank, The return type of zipn would have to depend on the number of arguments. If you are satisfied with all arguments having the same type, then you can use transpose: zipn list1 list2 .. listn = transpose [list1, list2, .. listn] Can we make a polyvariadic zipn that returns a [HList]? Seems like a neat challenge, but I'm a bit pressed for time right now. I'm afraid it would be pretty unwieldy. I'm looking forward to seeing solutions though. :-) -- Joel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] zip3, zip4 ... - zipn?
I was looking for something like this too. Note that Erlang can do this ;-) but Erlang is probably not so strongly typed, so it's easier to do? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] howto install ghc-6.7.* ?
i just don't get it. please, can anybody explaim me how to do that? i tried it the last few days with ghc-6.7.20070807, ghc-6.7.20070809, and ghc-6.7.20070810. it always results in a broken library (without Prelude): # ghc-pkg list /usr/local/lib/ghc-6.7.20070810/package.conf: {ghc-6.7.20070810}, rts-1.0 i did this on my gentoo-i386-box (pretty old, takes 1h for quick build, 3.5h without mk/build.mk): T=20070810 tar xjf ghc-6.7.$T-src.tar.bz2 tar xjf ghc-6.7.$T-src-extralibs.tar.bz2 cd ghc-6.7.$T ( #echo BuildFlavour = quick #cat mk/build.mk.sample echo HADDOCK_DOCS = YES ) mk/build.mk ./configure ( time nice -n 19 make all install ) those extralibs seem to be installed in /usr/local/lib/ghc-6.7.20070810/lib/ but registered in ghc-6.7.20070810/driver/package.conf.inplace instead of /usr/local/lib/ghc-6.7.20070810/package.conf . - marc pgpn4RY5OC2Kc.pgp Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] arrow question HXT related
Hi, I think this is just a stupid arrow question. Still I cannot find where my mistake is located. Suppose I have a simple xml document I want to process with HXT: root elem sub / risubtext/risub /elem /root After extracting elem I want to duplicate the children trees with the arrow operator () and process them to get each sub element, like I try in treMe2. Below the example code. While I can get each sub element with tryMe and tryMe1, tryMe2 will produce a []. Instead I want something like tryMe3. I think I'm missing something stupid but right now I just feel stupidly blind. Thanks for your help, Andrea import Text.XML.HXT.Arrow xml = rootelemsub /risubtext/risub/elem/root tryMe = runLA arrow [] where arrow = constA xml xread deep (hasName elem) getChildren (hasName risub getChildren getText) tryMe1 = runLA arrow [] where arrow = constA xml xread deep (hasName elem) getChildren (hasName sub withDefault (getChildren getText) ciao) tryMe2 = runLA arrow [] where arrow = constA xml xread deep (hasName elem) getChildren (hasName sub withDefault (getChildren getText) ciao) (hasName risub getChildren getText) tryMe3 = runLA arrow [] where arrow = constA xml xread constA first constA second The output: *test tryMe [text] *test tryMe1 [ciao] *test tryMe2 [] *test tryMe3 [(first,second)] *test ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Small question [new Wiki page up]
Stefan O'Rear wrote: Good idea! Maybe it could be fit into the GHC Performance Resource somehow? (http://www.haskell.org/haskellwiki/Performance/GHC) OK. But it'll probably contain a lot of guessing to start with... ;-) Wiki pages can be fixed. Private misunderstandings can't, at least not anywhere near as easily. A page now exists: http://www.haskell.org/haskellwiki/GHC_optimisations Everybody feel free to point and laugh. (Or, more helpfully, expand and correct!) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] arrow question HXT related
On Sat, Aug 11, 2007 at 11:50:19AM +0200, Andrea Rossato wrote: Hi, I think this is just a stupid arrow question. Still I cannot find where my mistake is located. well, it was not an arrow problem but a HXT problem. This new version of tryMe2 does work as expected: tryMe2 = runLA arrow [] where arrow = constA xml xread listA ( deep (hasName elem) (deep (hasName sub) withDefault (getChildren getText) ciao) (deep (hasName risub) getChildren getText) ) Sorry for the noise. Andrea ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Language support for imperative code. Was: Re: monad subexpressions
Brian Hulley schrieb: apfelmus wrote: However, most genuinely imperative things are often just a building block for a higher level functional model. The ByteString library is a good example: the interface is purely functional, the internals are explicit memory control. It's a bad idea to let the internal memory control leak out and pollute an otherwise purely functional program with IO-types. Regarding the quote above, if the API must hide explicit memory control from the user the only way I can see of doing this would be to use (unsafePerformIO), which really is unsafe since Haskell relies on the fact that mutable operations can't escape from the IO monad in order to get away with not having to impose a value restriction as in ML. Indeed, Data.ByteString makes heavy use of unsafePerformIO and inlinePerformIO. This is safe since it's just used for efficient memory access and (de-)allocation, the ByteStrings themselves are immutable. If you don't use (unsafePerformIO), then the slightest need for mutable data structures pollutes the entire interface. Well, any code that wants to mutate or read this data structure has to announce so in the type signature. However, it's debatable whether certain forms of mutation count as pollution. In fact, the simplest mutation is just a function s - s . Haskell is throughly polluted by such mutations: (3+) :: Int - Int ([1,2]++):: [Int] - [Int] insert x 3 :: Map String Int - Map String Int Of course, from the purely functional point of view, this is hardly perceived as mutation since the original value is not changed at all and still available. In other words, the need to change a value doesn't imply the need to discard (and thus mutate) the old one. Mutable data structures in the sense of ephemeral (= not persistent = update in-place) data structure indeed do introduce the need to work in ST since the old version is - by definition - not available anymore. This may be the right thing to do when the data structure is inherently used in a single-threaded fashion. However, most used-to-be ephemeral data structures have very good persistent counterparts in Haskell. In the end, the type just reflects the inherent difficulty of reasoning about ephemeral data structures. And that's what the quoted paper illustrates: persistent data structures are much easier to deal with. For example in the excellent paper you quoted N. Ramsey and J. Dias. An Applicative Control-Flow Graph Based on Huet's Zipper http://www.eecs.harvard.edu/~nr/pubs/zipcfg-abstract.html http://www.eecs.harvard.edu/%7Enr/pubs/zipcfg-abstract.html the authors are pleased to have found an Applicative solution, and indeed their solution has many useful and instructive aspects. However on page 111, hidden away in the definition of their API function to create a label, is a call to (ref 0) ;-) The equivalent implementation in Haskell would completely destroy all hope of using this in a pure context and force all use of the API into the IO monad. I don't know enough ML or have the background to judge whether this ref is really necessary, but I doubt that it can't be designed away. Haskell is designed so that any attempt at abstracting mutable local state will infect the entire program Depends on local. In general, I think is a good thing. The type reflects how difficult your program really is, nothing more, nothing less. That's how it is: persistent data and prue functions are sooo much easier to reason about. Implicit side effects just sweep the difficulty under the carpet. (I imagine a tool that makes implicit side effects explicitly visible in the types of say C or ML programs. I guess that people would scream whole nights when seeing the output of this tool on their programs and thus discovering how complicated the code really is ... Well, maybe not since they're used to it during debugging anyway.) But if the state is really local, no infection of the entire program takes place! The best example is probably indeed the Haskell Graphics library. The are pure functions for constructing graphics over:: Graphic - Graphic - Graphic polygon :: [Point] - Graphic and some IO-infected functions to draw those onto the screen drawInWindow :: Window - Graphic - IO () Now, Graphic may be implemented as an abstract data type and drawInWindow does the workload of interpreting it. Or, and that's how HGL currently implementes it, it can be an IO-action that encodes how to draw it type Graphics = Draw () ~= (Brush,Font,Pen) - IO () That is, every graphic is infested with IO but that doesn't spread to the API. (It does a bit with selectBrush but that can be corrected.) (modulo use of a highly dangerous function whose semantics is entirely unclear, depending on the vagaries of evaluation strategy of the particular compiler) (yes, unsafePerformIO clearly isn't for ephemeral data structures.) For
Re: [Haskell-cafe] How odd...
[Sorry for the long quote, but context is important] Dan Piponi wrote: It's fairly standard practice, when documenting functions of a complex variable, to specify precisely which 'branch cuts' are being used. Here's a quote from the Mathematica documentation describing their Log function: Log[z] has a branch cut discontinuity in the complex z plane running from -infinity to 0. With this interpretation, (-1)^(1/3) = 0.5 + sqrt(3)/2 * i. If you go with the real solution (-1) you might need to do so carefully in order to preserve other useful properties of ^, like continuity. You can guarantee this by making sure you make the right 'cuts'. If only it were that simple. Up until rather recently, it was not even known if there was a set of right cuts for ln and all the arc-trig functions that would work together properly. See `According to Abramowitz and Stegun or arccoth needn't be uncouth', by Corless, Jeffrey, Watt and Davenport, available from http://citeseer.ist.psu.edu/corless00according.html or http://www.apmaths.uwo.ca/~djeffrey/Offprints/couth.pdf This is by no means a solved problem. For example, there is still no consensus as to where the branch cuts for the various versions of the LegendreQ function should go. Jacques http://www.apmaths.uwo.ca/%7Edjeffrey/Offprints/couth.pdf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: zip3, zip4 ... - zipn?
Frank Buss schrieb: Is it possible to write a function like this: zipn n list_1 list_2 list_3 ... list_n which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable number of arguments are possible, like printf shows, so a general zipn should be possible, too. If it is possible, why there are functions like zip5 and not just zipn? What type would this function have? It's not possible to formulate this type in Haskell98. The problem is that the number of arguments cannot be determined statically, i.e. it depends on the value of n at run-time. There are languages more freaky than Haskell (like Agda or Epigram ) that can do that (without dynamic typing, that is!), they are called dependently typed. However, type-class hackery (or type synonym families once they're available in GHC) can be used to do something like that if you give the value of n at compile-time. I won't dwell into that, though. Also, applicative functors can help GHCi :m +Control.Applicative GHCi (\x y z - x*(y+z)) $ ZipList [1,2,3] * ZipList [-1,0,1] * ZipList [1,1,1] ZipList [0,2,6] GHCi (the second command is a single line.) Regards, apfelmus ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] zip3, zip4 ... - zipn?
On 8/11/07, Frank Buss [EMAIL PROTECTED] wrote: Is it possible to write a function like this: zipn n list_1 list_2 list_3 ... list_n which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable number of arguments are possible, like printf shows, so a general zipn should be possible, too. If it is possible, why there are functions like zip5 and not just zipn? Template Haskell can also be used to generate appropriate code for zipn (in fact, the original paper on TH even uses this as an example [1]). But again, this approach only works if the value of n is known at compile time. -Brent [1] http://www.haskell.org/th/papers/meta-haskell.ps ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Defining new operators
On 8/10/07, Shachaf Ben-Kiki [EMAIL PROTECTED] wrote: Also consider using: data Step = Step { ..., scenario :: Scenario, ... } Just to expand on Shachaf's answer, when defining a data type you can use a special record syntax to give names to each of the components, like this: data Monkey = M { species :: Species, color :: Color } This automatically gives you functions called 'species' and 'color' which you can apply to values of type Monkey to extract the relevant components. So in your case, you could write something like data Step = Step { ..., owner :: Scenario, ... } ...which would give you the 'owner' function you defined above for free, without having to type it out. To expand on Dan and Albert's answers, the 'functional idiom' would be to just write 'owner x' -- introducing something like a different definition of . to do 'record selection' might make things easier in the short term (i.e. if you are used to programming in an OO paradigm) but seems quite detrimental in the long term. Trying to force Haskell to look and feel like other languages you are used to is like taking two of the wheels off your Porsche because you are used to riding a bicycle. =) -Brent ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Dynamic thread management?
Hugh, I certainly think it would be wrong to declare that NDP is doomed to failure... not because you would be making an enemy of SPJ (I'm pretty sure you wouldn't!) but because it actually aims to solves a less ambitious problem: the problem of parallelising the SAME task applied to different data, rather than a collection of arbitrary tasks. Because the task does not change, we know that e.g. taking half the data cuts the amount of work in half. Therefore an up-front scheduling approach can work. If you fast forward to about 42 minutes into the London HUG video, you see that Simon talks about the problem of parallelizing (f x) + (g y), and says that he spent quite a lot of time in the eighties trying to make this game go fast [..] and the result was pretty much abject failure. You're absolutely right that a dynamic/adaptive approach is the only one that will work when the tasks are of unknown size. Whether this approach is as easy as you think is open for you to prove. I look forward to testing your VM implementation, or at the very least reading your paper on the subject ;-) Regards, Neil On 8/11/07, Hugh Perkins [EMAIL PROTECTED] wrote: On 8/11/07, Thomas Conway [EMAIL PROTECTED] wrote: There are many papers about this in the Parallel Logic Programming area. It is commonly called Embarrassing Parallelism. Ah, I wasnt very precise ;-) I didnt mean I dont understand the problem; I meant I dont understand why people think it is difficult to solve ;-) (And then I tried to explain by examples why it is easy, but it is true that my communication sucks ;-) ) you'll only get a benefit if you can break xs into chunks of e.g. 10^3 elements or more, and more like 10^5 or more for more usual 'f's. Actually, the number of elements is irrelevant. The only measure that is important is how long the function is taking to execute, and whether it is parellizable. Example, the following only has 3 elements but will take a while to run: strPrtLn $ sum $ map getNumberPrimes [1024, 2048, 4096 ] The following has 10 million elements but runs quickly: strPrtLn $ sum $ map (+1) [1..1000 ] In the second, we start the function running, in a single thread, and after a second, the function has already finished, so great! Were done! In the first, we start the function running, in a single thread. After a second the function is still running, so we look at what is taking the time and whether it is parallelizable. Turns out the vm has been chugging away on the map for the last second, and that that maps are parallelizeable, so we split the map into Math.Min( numberelements, number cores) pieces, which on a 1024-core machine, given we have 3 elements, is Math.Min( 1024, 3 ), which is 3. So, we assign each of the 3 elements of the map to a thread. So, now we're using 3 of our 64 cores. A second later, each thread is still chugging away at its element, so we think, ok, maybe we can parallelize more, because we still have 61 threads/cores available, so now we look at the getNumberOfPrimes function itself, and continue the above type of analysis. This continues until all 64 cores have been assigned some work to do. Whenever a thread finishes, we look around for some work for it to do. If there is some, we assign it. If there isnt, we look around for an existing thread that is doing something parallelizeable, and split it into two pieces, giving one to the old thread, and one to the available thread. Not sure why this is perceived as difficult (added the word perceived this time ;-) ). I think the main barrier to understanding why it is easy is understanding that this needs to be done from a VM, at runtime. It is not possible to do it statically at compilation, but I really need to finish watching SPJ's video before declaring that SPJ's proposal is doomed to fail ;-) Not least, probably not good to make an enemy of SPJ ;-) ___ 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] Re: zip3, zip4 ... - zipn?
On 8/11/07, apfelmus [EMAIL PROTECTED] wrote: Frank Buss schrieb: Is it possible to write a function like this: zipn n list_1 list_2 list_3 ... list_n which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable number of arguments are possible, like printf shows, so a general zipn should be possible, too. If it is possible, why there are functions like zip5 and not just zipn? What type would this function have? It's not possible to formulate this type in Haskell98. The problem is that the number of arguments cannot be determined statically, i.e. it depends on the value of n at run-time. There are languages more freaky than Haskell (like Agda or Epigram ) that can do that (without dynamic typing, that is!), they are called dependently typed. However, type-class hackery (or type synonym families once they're available in GHC) can be used to do something like that if you give the value of n at compile-time. I won't dwell into that, though. Also, applicative functors can help GHCi :m +Control.Applicative GHCi (\x y z - x*(y+z)) $ ZipList [1,2,3] * ZipList [-1,0,1] * ZipList [1,1,1] ZipList [0,2,6] GHCi (the second command is a single line.) Applicative functors can indeed help: (,,,) $ [1,2,3] * [-1,0,1] * [1,1,1] * [0,2,6] You just use n-1 commas when you want the effect of zipn. -Per ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Dynamic thread management?
You guys might also want to take a look at the Cilk programming language, and how it managed threads. If you know C, learning Cilk is about 2 hours of work, as it's C with half a dozen extra keywords and a few new concepts. I'd love to see Cilk - C + Haskell as a programming language. The key idea of Cilk is that it's easier to deparallelize than it is to parallelize, especially automatically. So the idea is that the program is written incredibly parallel, with huge numbers of microthreads, which are (on average) very cheap to spawn. The runtime then deparallelizes the microthreads, running multiple microthreads sequentially within a single real thread (a worker thread). Microthreads that live their entire life within a single real thread are cheap to spawn (as in not much more expensive than a normal function call cheap). The problem that Cilk runs into is that it's, well, C. It doesn't deal with contention at well at all- a single microthread blocking blocks the whole worker thread- meaning, among other things, that you can have false deadlocks, where one microthread blocks on another microthread in the same real thread, and thus acts like it's deadlocked even though it really isn't. You have greatly increased the likelyhood of raceconditions as well (mutable data and multithreading just don't mix). Plus you have all the normal fun you have with C bugs- wild pointers, buffer over runs, etc. All of which you avoid if you replace the C aspects of Cilk with Haskell. With STM you avoid the deadlock problem entirely, and with immutable data (except for carefully coded monads) you avoid the whole race condition problem. Plus all the normal advantages Haskell has over C. Just my $0.02. Brian On Sat, 11 Aug 2007, Neil Bartlett wrote: Hugh, I certainly think it would be wrong to declare that NDP is doomed to failure... not because you would be making an enemy of SPJ (I'm pretty sure you wouldn't!) but because it actually aims to solves a less ambitious problem: the problem of parallelising the SAME task applied to different data, rather than a collection of arbitrary tasks. Because the task does not change, we know that e.g. taking half the data cuts the amount of work in half. Therefore an up-front scheduling approach can work. If you fast forward to about 42 minutes into the London HUG video, you see that Simon talks about the problem of parallelizing (f x) + (g y), and says that he spent quite a lot of time in the eighties trying to make this game go fast [..] and the result was pretty much abject failure. You're absolutely right that a dynamic/adaptive approach is the only one that will work when the tasks are of unknown size. Whether this approach is as easy as you think is open for you to prove. I look forward to testing your VM implementation, or at the very least reading your paper on the subject ;-) Regards, Neil On 8/11/07, Hugh Perkins [EMAIL PROTECTED] wrote: On 8/11/07, Thomas Conway [EMAIL PROTECTED] wrote: There are many papers about this in the Parallel Logic Programming area. It is commonly called Embarrassing Parallelism. Ah, I wasnt very precise ;-) I didnt mean I dont understand the problem; I meant I dont understand why people think it is difficult to solve ;-) (And then I tried to explain by examples why it is easy, but it is true that my communication sucks ;-) ) you'll only get a benefit if you can break xs into chunks of e.g. 10^3 elements or more, and more like 10^5 or more for more usual 'f's. Actually, the number of elements is irrelevant. The only measure that is important is how long the function is taking to execute, and whether it is parellizable. Example, the following only has 3 elements but will take a while to run: strPrtLn $ sum $ map getNumberPrimes [1024, 2048, 4096 ] The following has 10 million elements but runs quickly: strPrtLn $ sum $ map (+1) [1..1000 ] In the second, we start the function running, in a single thread, and after a second, the function has already finished, so great! Were done! In the first, we start the function running, in a single thread. After a second the function is still running, so we look at what is taking the time and whether it is parallelizable. Turns out the vm has been chugging away on the map for the last second, and that that maps are parallelizeable, so we split the map into Math.Min( numberelements, number cores) pieces, which on a 1024-core machine, given we have 3 elements, is Math.Min( 1024, 3 ), which is 3. So, we assign each of the 3 elements of the map to a thread. So, now we're using 3 of our 64 cores. A second later, each thread is still chugging away at its element, so we think, ok, maybe we can parallelize more, because we still have 61 threads/cores available, so now we look at the getNumberOfPrimes function itself, and continue the above type of analysis. This continues until all 64 cores have been assigned some work to do. Whenever a
Re: [Haskell-cafe] Dynamic thread management?
Brian Hurt wrote: The key idea of Cilk is that it's easier to deparallelize than it is to parallelize, especially automatically. So the idea is that the program is written incredibly parallel, with huge numbers of microthreads, which are (on average) very cheap to spawn. The runtime then deparallelizes the microthreads, running multiple microthreads sequentially within a single real thread (a worker thread). Microthreads that live their entire life within a single real thread are cheap to spawn (as in not much more expensive than a normal function call cheap). That's so absurd, it might even work! I quite like the concept though - rather than asking what can we make parallel?, you say what should we do serially? That sounds like an easier question to answer... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Dynamic thread management?
On 11/08/07, Brian Hurt [EMAIL PROTECTED] wrote: You guys might also want to take a look at the Cilk programming language, and how it managed threads. If you know C, learning Cilk is about 2 hours of work, as it's C with half a dozen extra keywords and a few new concepts. I'd love to see Cilk - C + Haskell as a programming language. The key idea of Cilk is that it's easier to deparallelize than it is to parallelize, especially automatically. So the idea is that the program is written incredibly parallel, with huge numbers of microthreads, which are (on average) very cheap to spawn. The runtime then deparallelizes the microthreads, running multiple microthreads sequentially within a single real thread (a worker thread). Microthreads that live their entire life within a single real thread are cheap to spawn (as in not much more expensive than a normal function call cheap). The problem that Cilk runs into is that it's, well, C. It doesn't deal with contention at well at all- a single microthread blocking blocks the whole worker thread- meaning, among other things, that you can have false deadlocks, where one microthread blocks on another microthread in the same real thread, and thus acts like it's deadlocked even though it really isn't. You have greatly increased the likelyhood of raceconditions as well (mutable data and multithreading just don't mix). Plus you have all the normal fun you have with C bugs- wild pointers, buffer over runs, etc. All of which you avoid if you replace the C aspects of Cilk with Haskell. With STM you avoid the deadlock problem entirely, and with immutable data (except for carefully coded monads) you avoid the whole race condition problem. Plus all the normal advantages Haskell has over C. How is this any better than using par in Haskell? -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haddock: documenting parameters of functional arguments
I like to write documentation comments like fix :: ( a {- ^ local argument -} - a {- ^ local output -} ) - a {- ^ global output -} but Haddock doesn't allow it. Or is there a trick to get it work? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] Dynamic thread management?
Hello Brian, Saturday, August 11, 2007, 8:35:49 PM, you wrote: The key idea of Cilk is that it's easier to deparallelize than it is to parallelize, especially automatically. So the idea is that the program is written incredibly parallel, with huge numbers of microthreads, which are (on average) very cheap to spawn. The runtime then deparallelizes the microthreads, running multiple microthreads sequentially within a single real thread (a worker thread). this idea is in wide use now: it's how ghc, erlang, ruby and virtually any other interpreting languages work :)) -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Explaining monads
David Menendez wrote: Be sure to read sigpfe's You could have invented monads! and the Wadler paper. http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf Most tutorials try to explain what a monad *is*, but these focus more on why they're a useful way to organize code. In my experience, being able to use a monad is more important than understanding the theory. Hey, now I know what a monad is! What I missed in all those tutorials is that a monad is an *abstract base class*. With this realization, which I had after reading the sigfpe tutorial, everything makes sense for me. To review a basic OOP example, I can't illustrate what a Vehicle *is* in general terms. I can illustrate a Bicycle, a Car, a Boat, a Plane, a Submarine, a Hovercraft, a LARC-V, and many other examples of instances of /subclasses/ of Vehicle, but I can't find anything that's /just/ a Vehicle. In OOP, Vehicle is an abstract base class. The same thing applies for a Monad. I can look at lots and lots of instances, like Maybe, Either, List, State, Reader, Writer, IO, and lots of others, but I can't produce an example that's /just/ a Monad. Monad is an abstract base class, too. Now if I had to explain What is a Vehicle, I would have to say A Vehicle is a device that provides transportation. When asked for more details, I can specify the interface and provide examples of instances. Interface for Vehicle: load, unload, goto Instances of Vehicle: Bicycle, Car, Plane, Boat, etc. Given the question What is a Monad, I would have to say A Monad is a device for sequencing side-effects. When asked for more details, I can specify the interface and provide examples of instances. Interface for Monad: return, bind Instances of Monad: Maybe, Either, List, State, etc. What is particularly stupefying for me is that I missed the fact that Monad is obviously an abstract base class: Monad is declared as a type-class! Now the hard part. As far I currently know - and I could be wrong: (1) Monad, Comonad and Arrow are all abstract base classes. (2) Monad, Comonad and Arrow are all devices for sequencing side-effects. (3) Monad and Comonad are both specializations of Arrow. Given the question What is an Arrow, I would have to say An Arrow is a device for sequencing side-effects. When asked for more details, I can specify the interface and provide examples of instances. This leads directly to the question What makes a Monad special, compared to an Arrow? Right now, the clues I have are: (1) Every monad is equivalent to a Kleisli arrow. (2) The ArrowApply class is equivalent to the Monad class. I can restate the question: What is special about ArrowApply, compared to Arrow? I see that an arrow accepts some inputs, performs a computation, possibly with side-effects, and generates some outputs. In particular, suppose I create instances of Arrow that accept two inputs (as a pair) and produce one output. Some of these instances (i.e. ArrowApply) are special: I can provide, as the two inputs, (1) an Arrow that accepts one input and one output, and (2) an input suitable for that Arrow. The output that I get is the result of feeding input (2) to input (1) to get a result, *and* somehow combining the side-effects of both arrows. The only way an ArrowApply can combine the side effects of two arrows and still obey the Arrow laws is through an operation that takes an (arrow nested inside an arrow) and collapses it into a sigle arrow. That's exactly what join does for monads. So, ArrowApply is special, compared to Arrow, because ArrowApply has a join operation, but Arrow doesn't. Clear as mud! The question remains: What is special about Monad or ArrowApply, compared to Arrow? or What is more general about Arrow, compared to Monad or ArrowApply? -- Ron ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: zip3, zip4 ... - zipn?
Frank Buss [EMAIL PROTECTED] wrote in article [EMAIL PROTECTED] in gmane.comp.lang.haskell.cafe: Is it possible to write a function like this: zipn n list_1 list_2 list_3 ... list_n which implements zip3 for n=3, zip4 for n=4 etc.? Looks like variable number of arguments are possible, like printf shows, so a general zipn should be possible, too. If it is possible, why there are functions like zip5 and not just zipn? Check out: Fridlender, Daniel, and Mia Indrika. 2000. Do we need dependent types? Journal of Functional Programming 10(4):409-415. http://www.math.chalmers.se/~indrika/jfp.ps.gz McBride, Conor. 2002. Faking it: Simulating dependent types in Haskell. Journal of Functional Programming 12(4-5): 375-392. -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig Remember Hirosima 1945-08-06, Nagasaki 1945-08-09. http://petitions.pm.gov.uk/Free-Vanunu/ http://www.vanunu.org/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: default for quotRem in terms of divMod?
Btw. is there any application, where 'quot' and 'rem' are needed? All occurrences of 'quot' and 'rem' I found in code so far were actually wrong and should have been 'div' and 'mod'. http://www.haskell.org/haskellwiki/Things_to_avoid#Forget_about_quot_and_rem ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Explaining monads
On Sat, Aug 11, 2007 at 03:00:04PM -0400, Ronald Guida wrote: The question remains: What is special about Monad or ArrowApply, compared to Arrow? or What is more general about Arrow, compared to Monad or ArrowApply? If all you have is an Arrow, then you must make up your mind what you're going to do ahead of time. ArrowChoice gives you the ability to make basic yes or no decisions at run time. ArrowApply gives you arbitrary computed jumps. Sometimes it's useful to restrict what you can do. Duponcheel and Swierstra wrote a parser library as an Arrow; because it forced you to decide the parsing structure ahead of time, their library had enough information to build LR-type parsing tables, and thus to do yacc-style error correction. (Nobody found it useful enough to use, but it still makes a nice demonstration of why plain Arrow is sometimes better.) Conversely, some applications *need* the extra freedom. Imagine trying to write an interpreter for a toy language with I/O, and IO is a plain Arrow and not a Monad. You can read input and parse it, but you can't actually do IO because the IO you need to do, depends on the input you read - precisely what Arrow forbids! Stefan signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] zip3, zip4 ... - zipn?
On Sat, Aug 11, 2007 at 05:27:19PM +0800, Hugh Perkins wrote: I was looking for something like this too. Note that Erlang can do this ;-) but Erlang is probably not so strongly typed, so it's easier to do? I think the main issue is that Erlang doesn't use currying (IIRC). Currying makes it MUCH harder to implement varargs functions. (We thought this was a good tradeoff - partial applications give Haskell much more power than varargs would have.) (Unfortunately I don't know of any good languages with powerful type systems and vararg functions that can take advantage of powerful types... I'd love to give example code here :)) Stefan 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: default for quotRem in terms of divMod?
On Sat, 2007-08-11 at 21:10 +0200, Henning Thielemann wrote: Btw. is there any application, where 'quot' and 'rem' are needed? All occurrences of 'quot' and 'rem' I found in code so far were actually wrong and should have been 'div' and 'mod'. http://www.haskell.org/haskellwiki/Things_to_avoid#Forget_about_quot_and_rem quotRem is faster than divMod, and my understanding is that even divMod is arguably broken. http://www.cs.uu.nl/~daan/download/papers/divmodnote-letter.pdf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] howto install ghc-6.7.* ?
On Sat, Aug 11, 2007 at 11:44:17AM +0200, Marc A. Ziegert wrote: i just don't get it. please, can anybody explaim me how to do that? i tried it the last few days with ghc-6.7.20070807, ghc-6.7.20070809, and ghc-6.7.20070810. it always results in a broken library (without Prelude): # ghc-pkg list /usr/local/lib/ghc-6.7.20070810/package.conf: {ghc-6.7.20070810}, rts-1.0 i did this on my gentoo-i386-box (pretty old, takes 1h for quick build, 3.5h without mk/build.mk): T=20070810 tar xjf ghc-6.7.$T-src.tar.bz2 tar xjf ghc-6.7.$T-src-extralibs.tar.bz2 cd ghc-6.7.$T ( #echo BuildFlavour = quick #cat mk/build.mk.sample echo HADDOCK_DOCS = YES ) mk/build.mk ./configure ( time nice -n 19 make all install ) those extralibs seem to be installed in /usr/local/lib/ghc-6.7.20070810/lib/ but registered in ghc-6.7.20070810/driver/package.conf.inplace instead of /usr/local/lib/ghc-6.7.20070810/package.conf Last time I built GHC, I needed to run 'sh boot' right before configure. Don't know if this has anything to do with your problem, however. (It would also be a Good Idea to add 21 | tee -a make.log to that command line, and look at the logs afterward...) Stefan signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] IO within parser
I've been struggling with writing a parser that needs to parse include files within source files. So far I cannot get this to work (in reality to get work done I wrote a kludge that returns a list of include filenames to be run later in a pure IO function. I realized that this just amounted to creating my own half-assed monad system so I really don't want to use this approach). I have read the tutorials I could find on monad transformers but I still don't see what's going on. I'm using the Parsec parser library. Here's an simple example of what I've tried. I also tried using liftIO and got a message about needing to add an instance of MonadIO. This made more sense but the type of liftIO is baffling class Monad m = MonadIO m where liftIO :: IO a - m a But how do you define this function? There is no constructor for IO a that you can take apart. Anyway, here is the code that just uses lift. Keep in mind that the outer monad is just GenParser Char st [Char]. I'm guessing this is wrong and I should have a transformer monad as the outer layer. But which one? and how to use it? pio = do { s - many1 alphaNum; input - lift (readFile s); return input; } go6 = runParser pio () This is a test = ghc output from trying to load this is = Couldn't match kind `* - * - *' against `(* - *) - * - *' When matching the kinds of `GenParser Char :: * - * - *' and `t :: (* - *) - * - *' Expected type: GenParser Char st Inferred type: t IO In a 'do' expression: lift (writeFile Foo s) Fussy? Opinionated? Impossible to please? Perfect. Join Yahoo!'s user panel and lay it on us. http://surveylink.yahoo.com/gmrs/yahoo_panel_invite.asp?a=7 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] IO within parser
Gregory Propf wrote: I've been struggling with writing a parser that needs to parse include files within source files. So far I cannot get this to work (in reality to get work done I wrote a kludge that returns a list of include filenames to be run later in a pure IO function. I realized that this just amounted to creating my own half-assed monad system so I really don't want to use this approach). I have read the tutorials I could find on monad transformers but I still don't see what's going on. I'm using the Parsec parser library. Here's an simple example of what I've tried. I also tried using liftIO and got a message about needing to add an instance of MonadIO. This made more sense but the type of liftIO is baffling The fun part is that Parsec already has a feature for include files... (I can't remember where the heck it is or how you use it though.) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: zip3, zip4 ... - zipn?
Also, applicative functors can help GHCi :m +Control.Applicative GHCi (\x y z - x*(y+z)) $ ZipList [1,2,3] * ZipList [-1,0,1] * ZipList [1,1,1] ZipList [0,2,6] GHCi http://www.soi.city.ac.uk/~ross/papers/Applicative.pdf quote The general scheme is as follows: (page 2) Marc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: default for quotRem in terms of divMod?
Henning Thielemann wrote: Btw. is there any application, where 'quot' and 'rem' are needed? All occurrences of 'quot' and 'rem' I found in code so far were actually wrong and should have been 'div' and 'mod'. http://www.haskell.org/haskellwiki/Things_to_avoid#Forget_about_quot_and_rem Yes, my implementation of Integer in terms of lists of Int, deliberately uses the symmetry of quotRem in order to store negative numbers as the negation of all elements of the positive number, and be able to virtually ignore the signs most of the time. (Also because quotRem is usually faster, I figured it made sense to use that technique.) (It doesn't make any difference on numbers that cannot be negative, also.) Everywhere else I remember when coding, div/mod were the correct ones to use (even back when I was coding in C, I wished I had that rounding behavior some time). I do think that if you almost always want to _use_ div and mod, you should be able to just define div and mod too (not quot and rem) -- one reason I brought up the issue :) Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: default for quotRem in terms of divMod?
Isaac Dupree wrote: I do think that if you almost always want to _use_ div and mod, you should be able to just define div and mod too (not quot and rem) that was unclear - I mean you should have that choice, not that it should be disallowed to define quot and rem only! Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] howto install ghc-6.7.* ?
Same problem here. I downloaded the ghc-6.7.20070811.tar.bz2 snapshot build on amd64 under ubuntu. From the README The sh boot step is only necessary if this is a tree checked out from darcs. For source distributions downloaded from GHC's web site, this step has already been performed. On 8/11/07, Marc A. Ziegert [EMAIL PROTECTED] wrote: i just don't get it. please, can anybody explaim me how to do that? i tried it the last few days with ghc-6.7.20070807, ghc-6.7.20070809, and ghc-6.7.20070810. it always results in a broken library (without Prelude): # ghc-pkg list /usr/local/lib/ghc-6.7.20070810/package.conf: {ghc-6.7.20070810}, rts-1.0 i did this on my gentoo-i386-box (pretty old, takes 1h for quick build, 3.5h without mk/build.mk): T=20070810 tar xjf ghc-6.7.$T-src.tar.bz2 tar xjf ghc-6.7.$T-src-extralibs.tar.bz2 cd ghc-6.7.$T ( #echo BuildFlavour = quick #cat mk/build.mk.sample echo HADDOCK_DOCS = YES ) mk/build.mk ./configure ( time nice -n 19 make all install ) those extralibs seem to be installed in /usr/local/lib/ghc-6.7.20070810/lib/ but registered in ghc-6.7.20070810/driver/package.conf.inplace instead of /usr/local/lib/ghc-6.7.20070810/package.conf . - marc ___ 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] Dynamic thread management?
On Sat, 11 Aug 2007, Sebastian Sylvan wrote: How is this any better than using par in Haskell? Mainly how the threads are actually scheduled. Mind you, I'm an *incredible* Haskell newbie, so take all of my comments with a 5-pound salt block, but as I understand how the current implementation of parallel Haskell works, all threads spawned go into a communal heap. When a thread blocks, it's put back into the communal queue, and a new thread is selected to run by the worker thread. In Cilk, the task structure is more tree-like. When thread A spawns thread B, the worker thread stops executing thread A and starts executing thread B. When thread B exits, the worker thread then resumes thread A. So in any given point in time, the worker thread has a stack of processes waiting for subthreads to complete so they can be resumed- not unlike function calls in other languages, or nested lazy blocks in Haskell. When a worker thread runs out of work to do, when it has no more threads to execute, it picks another worker thread at random, and asks the other worker thread for work to do. The other worker thread (assuming it has work to do) then picks the microthread at the bottom of the resume stack, that is farthest away from being resumed, and passes that microthread's state to the original worker thread. From the user program's perspective, this is no different from the current implementation. Threads get spawned, get executed in some unspecified order, and then complete. What's interesting (to me, at least) are the optimization opportunities this model provides that the shared-queue model doesn't. Consider the following structural model: we have a two-tiered heap. Each worker thread has it's own local heap, which only microthreads it is managing can see. Plus there is a global heap with objects that all microthreads in all worker threads can see. Objects are originally allocated in the local heap. When a microthread to start being executed on another worker thread, all objects it can see (reach, in the conservative GC sense) are promoted to the global heap. The advantage of all of this is that now we can easily distinguish between objects that can be seen from other real threads, and those that can't. All of the mutable data structures- tvars, lazy thunks, everything- can be much more cheaply implemented if you know that no other thread can access them. Take the example of a parallel map, where I'm using a tvar in my map function. The likelyhood is that all of the (short-lived) microthreads I'm spawning will execute on the same worker thread- and that thus the tvar will never leave the local heap, and thus can be optimized down to something close to a single-threaded mvar. I have, via optimization, turned a parallel map and a synchronized tvar back into something approaching a serial map and an mvar. Brian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] zip3, zip4 ... - zipn?
On Sun, Aug 12, 2007 at 12:56:31PM +1000, Alexis Hazell wrote: On Sunday 12 August 2007 05:24, Stefan O'Rear wrote: Currying makes it MUCH harder to implement varargs functions. That's interesting - why is that the case? varsum 2 3 -- varsum receives 2, and returns a function, which when -- passed 3, returns 5 varsum 2 3 4 -- varsum receives 2, and returns a function, which when -- passed 3, returns a function that when passed 4 returns -- 9. Because of this, the number of arguments must somehow be passed out-of-band; but then the type of the whole function (usually) must depend on the control parameter, requiring dependent types. Stefan signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Infinity v0.1
Hello! Over the past couple of days I've been working on an IRC bot in the essence of lambdabot; that is, it should be extendable through plugins and plugins should be easy to write, modify and contribute. I also wanted the bot to be small in terms of LOC (as of 0.1, about ~360 including the two bundled plugins,) but still be usable. Well, now I have something to show for it, and I introduce infinity v0.1: http://austin.youareinferior.net/infinity-0.1.tar.gz (there is no darcs repo yet, although I have emailed someone about a possible account for darcs.haskell.org.) Everything from building to writing plugins should become fairly self evident from reading the README. You will need the hs-plugins to use it. As it stands, the bot is incredibly primitive and there are almost no plugins (I only wrote 'hello world' and 'goodbye world' plugins to test the code as it moved forward) as of yet, however, I had fun with this thing and I hope maybe someone could do something interesting with it. There're some parts of the code that I'm not particularly happy with. For the 0.2 release I have a couple of goals in mind: 1. To move the basic ad-hoc IRC parsing code (lots of drop and dropWhile and whatnot) to a more robust implementation such as parsec. This should hopefully clean up some of the code I'm not on good terms with. 2. To add support for in-situ reloading and re-compilation of modules, so you won't even have to restart the bot if you update a plugin. This will probably require some reworking of my threading code so that the environment stays safe and stable (STM?) 3. To move all of the built-in core commands to plugins as well; this will probably require encapsulating plugins in a monad (StateT) henceforth. I'm not exactly the most advanced haskell programmer ever born, but I enjoyed working on this code and while it isn't and probably won't ever be the next lambdabot, I hope someone can learn something from it or just have fun with it. If anybody would like to take the time to write a plugin or something for some interesting purpose, I would be happy to include it in the source tree (I'm sure you guys can come up with something more interesting than I can.) I would really appreciate any and all comments on the code. I still feel myself to be in an 'intermediate' area with Haskell, so anything you guys can add that would improve the code would be incredibly appreciated. PS: I've only tested this on an i386 linux box so if anybody here can confirm it works on other systems (bsd, solaris?) where hs-plugins is available, that would be awesome. Thanks! -- - Austin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: towards a new foundation for set theory with atoms
On Fri, Aug 10, 2007 at 03:54:23PM -0700, Greg Meredith wrote: Haskellians, A quick follow up. If you look at the code that i have written there is a great deal of repeated structure. Each of these different kinds of sets and atoms are isomorphic copies of each other. Because, however, of the alternation discipline, i could see no way to abstract the structure and simplify the code. Perhaps someone better versed in the Haskellian mysteries could enlighten me. You could take a less absolute view of the game, and describe each node instead locally from the perspective of a player. Imagine Alice Bob and Carol sitting around a table: data ThreePlayers a b c = Next (ThreePlayer b c a) | Prev (ThreePlayers c a b) In general you can get subgroups of a symmetric group as your sets of colors this way (i.e, the set of elements of any group), I'm not quite sure how much freedom you have in the sets of allowed transitions (in particular, making some of the argument types identical can break symmetry). You could also go for the obvious big hammer, pretend that Haskell has a strongly normalizing subset and encode inequality explicitly with GADTs and such. date Eq a b where Refl a a data False type Neq a b = Eq a b - False -- might be trouble if a and b are only equal non-constructively? data Red = Red data Green = Green data Set color where Red :: Neq Red color - Set Red - Set color ... Brandon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Fw: [Haskell-cafe] IO within parser
Well the docs ( http://legacy.cs.uu.nl/daan/download/parsec/parsec.html ) hint that setInput and getInput are good for this. I can certainly how they *would* be - if I knew how to pull in files within the parse. Actually I use those functions to do multiple recursive passes but of course you already have the output from the first pass in the parser there. runParser only *looks* like it takes input from a file. Actually it just parses the string you give it and uses the filename arg for error messages only. You still need a way to pull the data into the string from the file. (Note: I accidentally sent this to Andrew instead of the list originally) - Original Message From: Andrew Coppin [EMAIL PROTECTED] To: haskell-cafe@haskell.org Sent: Saturday, August 11, 2007 1:25:16 PM Subject: Re: [Haskell-cafe] IO within parser Gregory Propf wrote: I've been struggling with writing a parser that needs to parse include files within source files. So far I cannot get this to work (in reality to get work done I wrote a kludge that returns a list of include filenames to be run later in a pure IO function. I realized that this just amounted to creating my own half-assed monad system so I really don't want to use this approach). I have read the tutorials I could find on monad transformers but I still don't see what's going on. I'm using the Parsec parser library. Here's an simple example of what I've tried. I also tried using liftIO and got a message about needing to add an instance of MonadIO. This made more sense but the type of liftIO is baffling The fun part is that Parsec already has a feature for include files... (I can't remember where the heck it is or how you use it though.) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe Fussy? Opinionated? Impossible to please? Perfect. Join Yahoo!'s user panel and lay it on us. Choose the right car based on your needs. Check out Yahoo! Autos new Car Finder tool. http://autos.yahoo.com/carfinder/___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe