Re: [Haskell-cafe] Re: Monad for HOAS?
On Wed, May 14, 2008 at 06:01:37PM -0400, Chung-chieh Shan wrote: Conal Elliott [EMAIL PROTECTED] wrote in article [EMAIL PROTECTED] in gmane.comp.lang.haskell.cafe: I share your perspective, Edsko. If foo and (Let foo id) are indistinguishable to clients of your module and are equal with respect to your intended semantics of Exp, then I'd say at least this one monad law holds. - Conal I am at least sympathetic to this perspective, but the Expr constructors are not as polymorphic as the monad operations: if in do a - foo return a foo has type ExprM String (perhaps foo is equal to return []), then we want to generate the DSL expression Let [] id, but [] is not of type Expr. Because whenever foo's type is not ExprM Expr the above code using do notation must be exactly equal to foo, by parametricity even when foo's type is ExprM Expr we cannot generate Let. Yes, absolutely. This is the core difficulty in designing the monad, and the reason why I started experimenting with adding a type constructor to Expr data Expr a = One | Add (Expr a) (Expr a) | Let (Expr a) (Expr a - Expr a) | Place a This is useful regardless, because we can now define catamorphisms over Expr. Nevertheless, I still can't see how to define my monad properly (other than using Lauri's suggestion, which has already improved the readability of my code). Return is now easy (return = Place), and it should be relatively easy to define a join operation Expr (Expr a) - Expr a *but* since Expr uses HOAS, it is not an instance of Functor and so we cannot use the join operator to define return. Actually, I think this approach is a dead end too, but I'm not 100% sure. Edsko ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Richer (than ascii) notation for haskell source?
Brandon S. Allbery KF8NH wrote: Adjacent different scripts in general is probably a reasonable token discriminator. A token combining LTR and RTL, for example, is just confusing. So you would like to ban identifiers that contain both letters and digits for those who happen to speak languages whose letters are RTL? I must protest. Regards, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Richer (than ascii) notation for haskell source?
Brandon S. Allbery KF8NH wrote: Come to think of it, if you're after math notation, enough Greek letters are used as symbols that it might be necessary to just exclude them from use as letters. While I have not yet noticed anyone from Greece on this list, I don't think it would be appropriate for us to discriminate against Greek speakers as a built-in feature of Haskell. Regards, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Richer (than ascii) notation for haskell source?
Yitzchak Gale [EMAIL PROTECTED] wrote: Brandon S. Allbery KF8NH wrote: Come to think of it, if you're after math notation, enough Greek letters are used as symbols that it might be necessary to just exclude them from use as letters. While I have not yet noticed anyone from Greece on this list, I don't think it would be appropriate for us to discriminate against Greek speakers as a built-in feature of Haskell. /me shudders and tries not to remember those occasions when he read code written in french. It's quite akin to decompiled obfuscated Java-code, where you're left with classes say a-j and mostly functions with the name a, discerned by types. Code should be written completely in English, for practical reasons. -- (c) this sig last receiving data processing entity. Inspect headers for past copyright information. All rights reserved. Unauthorised copying, hiring, renting, public performance and/or broadcasting of this signature prohibited. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: GHC API GSoc project
Claus, thanks for taking the time to articulate all this, speaking as the mentor for the project this material is invaluable. I'd particularly like to see a wiki page collecting issues, plans and priorities too. My own priority is to have the compilation phases exposed. One (selfish) reason for this is that it will force a number of refactorings and cleanups inside GHC, that we've had on the radar for some time. As soon as there's a wiki page up I can start downloading some of the contents of my whiteboard onto it :-) Keeping track of comments in the parser sounds like a high priority to me, because we have an active customer (Haddock) to drive the design and test it. Another active customer is Yi, as I understand it they are using the GHC API to provide the features we had in Visual Haskell. This will be useful for driving the aspects of the design that IDEs need. Cheers, Simon Claus Reinke wrote: thanks, I was wondering about your project. Is there a project page documenting the issues/tickets you look at, and particularly the plan of attack as it changes in the face of reality?-) I've found http://code.google.com/soc/2008/haskell/appinfo.html?csaid=4189AF2C8AE5E25A which covers a lot of ground, and some interesting issues, but is so general (and design- rather than application-driven) that I've been worried about how much of it you'll manage (and with which priorities), given that the GHC API is indeed exposed rather than designed and may thus interfere with your good intentions in unexpected ways. Also, there are very different user needs out there, some want just analysis or some information extraction, some want source transformation capabilities, some want a stable portable hs-plugins replacement, some want to work with backends, etc. . you can't please everyone, but until your focus is known, people can't easily complain about your priorities. IMHO, trying to support a semantics- and comment-preserving roundtrip in (pretty . parse) would be a good way to start (David says he's going to look at the extracting comments/pragmas part, but they still need to be put back in during pretty printing). It sounds simple, and if it is, it will enable a lot more usage of the GHC API; and if it turns out not to be simple, you'll have a first sign of what you're up against, and can adjust your expectations!-) Making yourself available as you've done here I'm here; I'm going to work on this now; please cc me if you want to express your priorities sounds like a good way to pull together the many strands of interests relating to the GHC API. Now we all have to dust off our old wouldn't it be nice if the API could do this and thats. Perhaps something similar to what the type family folks are doing would help: use the ticket tracker for individual issues, have test cases that demonstrate the issues and their resolution, have more detailed documents online elsewhere, and a single wiki page to tie everything together (making it easier to find relevant tickets and the state of the art). [cf http://hackage.haskell.org/trac/ghc/wiki/TypeFunctionsStatus ] over the years, quite a few issues have been raised as tickets/ email/source comments, so collecting them would be a good way to get an idea of what is needed, deciding which of those issues would take how much effort would be a first useful contribution, and seeing which of these you intend to tackle would give the community at large a better chance to comment on your priorities in relation to their needs. I also hope you are in touch with Chaddaï - the port of HaRe to the GHC API did not make it as a GSoC project, but I understand he is going to do some work in this direction anyway. Looking forward to an improved GHC API!-) Claus ps. here are some first entries for your list, and for other interested parties following along (I'd be very interested to hear about your progress): - http://code.google.com/soc/2008/haskell/appinfo.html?csaid=4189AF2C8AE5E25A (project outline) - http://hackage.haskell.org/trac/ghc/ticket/1467 (GHC API: expose separate compilation stages; your main ticket so far?) - concerning exposed phases, it would also be useful if the interface was more uniform (eg., AST, typed AST,..) - search for NOTE in ghc/compiler/main/GHC.hs for some related notes from an earlier GHC/HaRe meeting - is it possible to use standalone deriving to get a generic programming framework over the ASTs without blowing up GHC's code for its own use (deriving Data, etc.)? - http://www.haskell.org/pipermail/haskell-cafe/2008-May/042616.html (GHC API: how to get the typechecked AST?) - http://hackage.haskell.org/trac/ghc/ticket/1886 (GHC API should preserve and provide access to comments) - dynamic loading of Haskell code, ala hs-plugins, but without the version/platform issues (GHCi has to be able to do this anyway, but it would be nice to have the ugly bits hidden, such as
Re: [Haskell-cafe] Re: Richer (than ascii) notation for haskell source?
Brandon S. Allbery KF8NH wrote: Come to think of it, if you're after math notation, enough Greek letters are used as symbols that it might be necessary to just exclude them from use as letters. Yitz Gale wrote: While I have not yet noticed anyone from Greece on this list, I don't think it would be appropriate for us to discriminate against Greek speakers as a built-in feature of Haskell. Achim Schneider wrote: /me shudders and tries not to remember those occasions when he read code written in french. He he, yes. I've seen C++ written in transliterated Russian, too. Very amusing - as long as I'm not the one who has to debug it. Code should be written completely in English, for practical reasons. Yes, of course, that's the standard today for software development. But I'm just saying that it would not be a good idea to hard-wire that policy into our language syntax. Just as an example - let's say you want to create an embedded DSL for speakers of a language other than English. The point is that it is always best to keep language syntax as simple as possible, for many reasons. In the case of Unicode, that means staying as close as possible to the spirit of Unicode and minimizing our own ad hoc rules. Adding one more keyword is way simpler than adding a bunch of complex rules to the lexer. A lot less moving parts to break. Especially if those lexer rules are not so consistent with built-in Unicode concepts such as letter and symbol, glyph direction, etc. So I think the best and simplest idea is to make the letter lambda a keyword. True, you need a space after it then. You already need spaces between the variables after the lambda, so anyway you might say that would be more consistent. I always find my thumb hovering indecisively over the space bar when I type a backslash lambda in Haskell. Haskell syntax has always been inspired by mathematical notation and reminiscent of it, never identical to it. Regards, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: GHC API GSoc project
My own priority is to have the compilation phases exposed. One (selfish) reason for this is that it will force a number of refactorings and cleanups inside GHC, that we've had on the radar for some time. As soon as there's a wiki page up I can start downloading some of the contents of my whiteboard onto it :-) This aspect is going to affect my own project, GHC plugins. Plugins need to be able to register their own compilation phases and when they should be run with the compiler. A nice way to do this might be to encode the current GHC stage inter-dependencies in code. Plugins could then add their own stages with similar dependency information and finally GHC would compute a topological sort based on the constraints as the actual order in which to run stages. These codified dependencies would complement any documentation based approach. I sketched a very rough idea of what that could look like at http://hackage.haskell.org/trac/ghc/wiki/Plugins (see note [Declarative Core Pass Placement]). I don't have the bandwidth to seriously think about these issues until after exams, but there are other things GHC-API related things that need to happen for plugins: - Expose the Core representation with documentation - Expose and document internal functions for manipulating Core (e.g. CoreUtil, DsUtil) I'm happy to do this work myself, but I need to be sure it's relatively coordinated with Thomas' work and the intentions for the compiler passes so we don't step on each others toes. Cheers, Max ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC API GSoc project (was: ANN: Haddock version 2.1.0)
2008/5/15, Claus Reinke [EMAIL PROTECTED]: - is it possible to use standalone deriving to get a generic programming framework over the ASTs without blowing up GHC's code for its own use (deriving Data, etc.)? Speaking of generics, I'm working on deriving Data.Traversable for GHC's abstract syntax using the derive package (I should give most credit to Twan here -- he has been modifying the derive package to make this possible). A package of some form that exports these instances should be useful to GHC API clients. David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] bottomless Top?
Folks [statutory warning: functors, terminal objects, unsafeCoerce] I had a peculiar notion this morning to wonder whether I could get away with shape :: Functor f = f a - f () shape fa = unsafeCoerce fa Sure enough, ghci gives me *Top shape moo [(),(),()] *Top shape [undefined] [*** Exception: Prelude.undefined which shows that pattern matching does just enough work to check that an element of () isn't bottom. I'm just wondering if that's really what's happening, what other implementations do, and how the garbage collector would react: would all those a's hang around for as long as the shape? I'm also wondering whether it makes sense to have a bottomless Top type, with constructor _ and lazy pattern _ (with (undefined :: Top) equal to _). Then the constant-time shape operator makes the same sort of sense as the constant-time inflate :: Functor f = f Zero - f a Any thoughts on either or both? Cheers Conor ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Two-iteration optimisation (was: GHC Predictability)
Don Stewart wrote: You'd want a general fusion framework for this... Stream fusion... at least does this for zips... but for an arbitrary 'f' instead of zip, seems harder. And of course, you wouldn't want that: f xs = xs : map expensiveCalculation xs Please don't fuse those two loops into one. In the case of mean, the outer function in question is /, and that is a good candidate for fusion because it is strict in both arguments. I think Don is right. There is a lot of room for expanding the scope of fusion, but it needs to be done one function at a time until our strictness analysis gets better. In the general case, I like the way things work now. The original complaint about unpredictability is, in my opinion, a bug in the documentation. This is yet another concept whose basics need to be made much more accessible to newbies. -Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] bottomless Top?
Replying slap-foreheadedly to own post... On 15 May 2008, at 11:56, Conor McBride wrote: Folks I'm also wondering whether it makes sense to have a bottomless Top type, with constructor _ and lazy pattern _ (with (undefined :: Top) equal to _). Then the constant-time shape operator makes the same sort of sense as the constant-time inflate :: Functor f = f Zero - f a We've got it already. data One would do, with smart constructor only :: One only = undefined and no other operations, so no way to be strict in its values. It's the lazy version of Zero. Assuming (safely?) that representation of data in each instance of a type constructor is uniform, that means shape :: Functor f = f a - f One shape = unsafeCoerce should be ok, right? The question about the GC implications of that move still stands, though. Cheers Conor ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Richer (than ascii) notation for haskell source?
On 2008 May 15, at 3:03, Yitzchak Gale wrote: Brandon S. Allbery KF8NH wrote: Adjacent different scripts in general is probably a reasonable token discriminator. A token combining LTR and RTL, for example, is just confusing. So you would like to ban identifiers that contain both letters and digits for those who happen to speak languages whose letters are RTL? I must protest. Mmmm, more specification needed. Add letter to the constraint. (compressing messages) As to your assertion of discrimination against Greek: my point was that mathematical notation *already* discriminates against speakers of Greek by appropriating their alphabet for its own purposes, so if you want to enable a mathematical-notation language mode it's already difficult to support a Greek localization. (I do wonder how modern Greek mathematicians deal with this) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Richer (than ascii) notation for haskell source?
On 2008 May 15, at 3:25, Achim Schneider wrote: Yitzchak Gale [EMAIL PROTECTED] wrote: Brandon S. Allbery KF8NH wrote: Come to think of it, if you're after math notation, enough Greek letters are used as symbols that it might be necessary to just exclude them from use as letters. While I have not yet noticed anyone from Greece on this list, I don't think it would be appropriate for us to discriminate against Greek speakers as a built-in feature of Haskell. /me shudders and tries not to remember those occasions when he read code written in french. So far I've had to deal with: French, Spanish, German, Swedish, Russian (transliterated), Hebrew (transliterated), Arabic (transliterated). I've also dealt with serious spaghetti code (I'm a Perl programmer in my day job, 'nuff said). I'll take the former, thanks. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Richer (than ascii) notation for haskell source?
On 2008 May 15, at 4:33, Yitzchak Gale wrote: Brandon S. Allbery KF8NH wrote: Come to think of it, if you're after math notation, enough Greek letters are used as symbols that it might be necessary to just exclude them from use as letters. Yitz Gale wrote: While I have not yet noticed anyone from Greece on this list, I don't think it would be appropriate for us to discriminate against Greek speakers as a built-in feature of Haskell. Achim Schneider wrote: /me shudders and tries not to remember those occasions when he read code written in french. He he, yes. I've seen C++ written in transliterated Russian, too. Very amusing - as long as I'm not the one who has to debug it. True --- as one of the people who generally gets to fire-test heimdal (http://h5l.org ) and feed back changes, it's always fun to debug those parts where variable names and comments are in Svensk. Code should be written completely in English, for practical reasons. Yes, of course, that's the standard today for software development. But I'm just saying that it would not be a good idea to hard-wire that policy into our language syntax. Suddenly I'm thinking of Lingua::Romana::Perligata I always find my thumb hovering indecisively over the space bar when I type a backslash lambda in Haskell. Come to think of it, I find myself inserting spaces anyway because of emacs' tendency to use backslash as an escape character (and because I'm so used to it being an escaper instead of an active character in its own right). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] saner shootout programs
Bulat Ziganshin wrote: Hello Richard, Yes it was just a plausible guess, but not contradicted by the experts. And that was using the Windows version of GHC so other versions may have better optimisation. I don't know how to check, maybe the experts can illuminate the subject? note that my letter was not contradicted too LOL 1. many experts just don't read this list due to its high traffic, write into ghc-users instead Good point. I have started a thread here http://www.haskell.org/pipermail/glasgow-haskell-users/2008-May/014742.html 2. ghc is too large system and no one know all its details. this particular option may be set up 10 years ago and never touched/studied by anyone since then. for example, i'm ghc performance expert [to some degree], but i don't know anything about its build system. all that i can tell is that ghc base library build times don't prohibit use of -O2 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Short circuiting and the Maybe monad
On Wed, May 14, 2008 at 1:38 AM, Janis Voigtlaender [EMAIL PROTECTED] wrote: Graham Fawcett wrote: Yes, but that's still a 'quick' short-circuiting. In your example, if 'n' is Nothing, then the 'f = g = h' thunks will not be forced (thanks to lazy evaluation), regardless of associativity. Tracing verifies this: No, it doesn't. What your tracing verifies is that the f, g, and h will not be evaluated. It doesn't verify that the 'f = g = h' part of the expression causes no evaluation overhead. Because that is not true. I didn't mean to suggest that. I confess to using 'the f = g = h thunks' as a shorthand for the thunks for f, g and h, and not for the binding expressions. I did write later in my message that there would be evaluation overhead, but that I suspected it would be negligible (an imprecise and hand-waving statement, to be sure). Consider the following: import Debug.Trace data Maybe' a = Nothing' | Just' a deriving Show instance Monad Maybe' where return = Just' Nothing' = _ = trace match Nothing' Just' a = k = k a Neat, I've never seen a bind operator used in a pattern. Thanks for this example. talk s = Just' . (trace s) f = talk --f g = talk --g h = talk --h foo n = n = f = g = h Now: *Main foo Nothing' match match match Nothing' So you get three pattern-matches on Nothing', where with the associative variant foo' n = n = \a - f a = \b - g b = h you get only one: *Main foo' Nothing' match Nothing' For a way to obtain such improvements automatically, and without touching the code, you may want to look into http://wwwtcs.inf.tu-dresden.de/~voigt/mpc08.pdf Much appreciated, Janis, I look forward to reading the paper. Graham Ciao, Janis. -- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Richer (than ascii) notation for haskell source?
2008/5/15 Yitzchak Gale [EMAIL PROTECTED]: So I think the best and simplest idea is to make the letter lambda a keyword. True, you need a space after it then. You already need spaces between the variables after the lambda, so anyway you might say that would be more consistent. You could use a zero width space (U+200B) to preserve the appearance of mathematical notation. I don't know if this is already treated as whitespace but it probably should be. There are also several thin space characters (U+2008 punctuation space, U+2009 thin space, U+200A hair space) that might be better, particularly between variables in a multi-parameter lambda. Andy ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FFI: newbie linking problem
Hi all, I found a solution to my linking problem, but it's a bit scary and I'm wondering if there is a simpler way to do this: The solution comes from the following article: http://www.emmestech.com/moron_guides/moron1.html To get ghc to link my dll properly I had to do the following: 1. Create a .def file from the sapnwrfc.lib using pexports.exe: 'pexports sapnwrfc.lib sapnwrfc.def' 2. Edit the sapnwrfc.def file to add @24 at the end of the function I must call. ... RfcSubmitTransaction RfcTraceTest [EMAIL PROTECTED] -- here ... 3. Create a 'sapnwrfc.a' import library using dlltool: 'dlltool --input-def sapnwrfc.def --dllname sapnwrfc.dll --output-lib libsapnwrfc.a -k' Is there a simpler way to do this? Some way of tricking ghc to search for RfcUTF8ToSAPUC instead of [EMAIL PROTECTED] It looks like ghc/ld/gcc (whoever is responsible) adds a @24 (number depends of args) at the end of the function name when the function is called using stdcall convention. Thanks, Olivier. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: GHC API GSoc project (was: ANN: Haddock version 2.1.0)
Thanks a lot for your comprehensive response, Claus! Per your suggestion, I started a GHC wiki page at http:// hackage.haskell.org/trac/ghc/wiki/GhcApiStatus. I added your comments and I will continue to add more things as I find them. I am closely following the Yi project and I am aware that the HaRe project needs some help from my side. I am interested that both projects become more usable and useful, so I'll be looking forward to concrete requests from both sides. I am also aware of Max's project. We certainly have to look out not to get into each other's ways but as I understand it Max will work on lower-level transformations, while I will concentrate on the front- end. We should therefore be able to keep our work fairly separate. thanks, I was wondering about your project. Is there a project page documenting the issues/tickets you look at, and particularly the plan of attack as it changes in the face of reality?-) I've found http://code.google.com/soc/2008/haskell/appinfo.html? csaid=4189AF2C8AE5E25A which covers a lot of ground, and some interesting issues, but is so general (and design- rather than application-driven) that I've been worried about how much of it you'll manage (and with which priorities), given that the GHC API is indeed exposed rather than designed and may thus interfere with your good intentions in unexpected ways. Yes, I tried to comment on this a little on the wiki page. I will also do an internship at MSR beginning in October. The topic isn't decided upon, yet, but working on the GHC API was among the things I proposed. Also, there are very different user needs out there, some want just analysis or some information extraction, some want source transformation capabilities, some want a stable portable hs-plugins replacement, some want to work with backends, etc. . you can't please everyone, but until your focus is known, people can't easily complain about your priorities. I will start with extracting semantic information from Haskell code. Things that are useful for Yi or HaRe. But if people give good arguments for other features I'd be willing to change priorities. Of course, Simon will have a word there, too. :) IMHO, trying to support a semantics- and comment-preserving roundtrip in (pretty . parse) would be a good way to start (David says he's going to look at the extracting comments/pragmas part, but they still need to be put back in during pretty printing). It sounds simple, and if it is, it will enable a lot more usage of the GHC API; and if it turns out not to be simple, you'll have a first sign of what you're up against, and can adjust your expectations!-) I agree. This looks like a good getting-up-to-speed topic. Making yourself available as you've done here I'm here; I'm going to work on this now; please cc me if you want to express your priorities sounds like a good way to pull together the many strands of interests relating to the GHC API. Now we all have to dust off our old wouldn't it be nice if the API could do this and thats. I'm looking forward to a lot of those responses, and I will try and dig around in the archives to find some of those myself. / Thomas -- My God's will / becomes me. / When he speaks out, / he speaks through me. / He has needs / like I do. / We both want / to rape you. PGP.sig Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] runInteractiveCommand: program ends before writing or reading all the output
2008/5/15 Olivier Boudry [EMAIL PROTECTED]: Hi all, It's the first time I use the runInteractiveCommand and I was probably bitten by laziness. When I run the following program and send its output to a file using '' redirection I get the full output of the called process. But if I run it in the console I get only half of the output. As console is slower than disk I assume the called process terminates before all data has been read from it or the main process terminates before data has been written to stdout. I thought using waitForProcess, closing called process output and flushing stdout would solve the problem but it doesn't. -- Compile with -threaded option module Main where import Control.Concurrent (forkIO) import System.Environment (getArgs) import System.FilePath (dropExtension, takeFileName) import System.IO (Handle, hClose, hFlush, hGetContents, stdout) import System.Process (runInteractiveCommand, waitForProcess) main :: IO () main = do (file:_) - getArgs (_, out, _, pid) - runInteractiveCommand $ dumpbin /EXPORTS ++ file forkIO (createDefFile file out) waitForProcess pid hClose out hFlush stdout createDefFile :: String - Handle - IO () createDefFile file inp = do putStrLn $ LIBRARY ++ (dropExtension . takeFileName) file ++ .dll putStrLn EXPORTS text - hGetContents inp mapM_ writeExport $ keepExports $ map words $ lines text where keepExports :: [[String]] - [String] keepExports = map head . filter (not . null) . takeWhile ([Summary]/=) . drop 1 . dropWhile ([ordinal,name]/=) writeExport ('_':xs) = putStrLn xs writeExport xs = putStrLn xs Any idea regarding the cause of this problem? I think I've encountered the same problem several times, and it was because I was reading from the handle lazily, like this: (_, out, _, pid) - runInteractiveProcess ... str - hGetContents out waitForProcess pid But I didn't use 'str' until after the process finishes. My solution was to use strict IO, usually by replacing String with a strict ByteString. I hear there is now a library that lets you do strict IO with Strings Hope this helps. Thanks, Olivier. ___ 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
[Haskell-cafe] Write Haskell as fast as C. [Was: Re: GHC predictability]
I offer up the following example: mean xs = sum xs / length xs Now try, say, mean [1.. 1e9], and watch GHC eat several GB of RAM. (!!) If we now rearrange this to mean = (\(s,n) - s / n) . foldr (\x (s,n) - let s' = s+x; n' = n+1 in s' `seq` n' `seq` (s', n')) (0,0) and run the same example, and watch it run in constant space. Of course, the first version is clearly readable, while the second one is almost utterly incomprehensible, especially to a beginner. (It's even more fun that you need all those seq calls in there to make it work properly.) The sad fact is that if you just write something in Haskell in a nice, declarative style, then roughly 20% of the time you get good performance, and 80% of the time you get laughably poor performance. I've written an extended post on how to understand and reliably optimise code like this, looking at it all the way down to the assembly. The result are some simple rules to follow for generated code as good as gcc -O2. Enjoy, http://cgi.cse.unsw.edu.au/~dons/blog/2008/05/16#fast -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] runInteractiveCommand: program ends before writing or reading all the output
It looks like a simple race condition to me. You are using waitForProcess pid to wait for runInteractiveCommand to finish, but you don't seem to have anything that waits for createDefFile to finish. main :: IO () main = do (file:_) - getArgs (_, out, _, pid) - runInteractiveCommand $ dumpbin /EXPORTS ++ file forkIO (createDefFile file out) waitForProcess pid hClose out hFlush stdout ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] runInteractiveCommand: program ends before writing or reading all the output
On Thu, May 15, 2008 at 11:42 AM, Ronald Guida [EMAIL PROTECTED] wrote: It looks like a simple race condition to me. You are using waitForProcess pid to wait for runInteractiveCommand to finish, but you don't seem to have anything that waits for createDefFile to finish. Whoops, sorry, I didn't read the original post closely enough. main :: IO () main = do (file:_) - getArgs (_, out, _, pid) - runInteractiveCommand $ dumpbin /EXPORTS ++ file forkIO (createDefFile file out) waitForProcess pid hClose out hFlush stdout ___ 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] Write Haskell as fast as C. [Was: Re: GHC predictability]
On Thu, 2008-05-15 at 11:31 -0700, Don Stewart wrote: I've written an extended post on how to understand and reliably optimise code like this, looking at it all the way down to the assembly. The result are some simple rules to follow for generated code as good as gcc -O2. Enjoy, http://cgi.cse.unsw.edu.au/~dons/blog/2008/05/16#fast A good read. Side point: Is the name go part of the idiom you mentioned? I sometimes use the same practise but usually just calls the worker the same as the real function with an added prime ('). signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] runInteractiveCommand: program ends before writing or reading all the output
On Thu, May 15, 2008 at 2:42 PM, Ronald Guida [EMAIL PROTECTED] wrote: It looks like a simple race condition to me. You are using waitForProcess pid to wait for runInteractiveCommand to finish, but you don't seem to have anything that waits for createDefFile to finish. Thanks Ronald, As I could not find a function to wait on a ThreadId I used a MVar to synchronize both threads. sync - newEmptyMVar forkIO (createDefFile sync file out) waitForProcess pid takeMVar sync and at the end of the forked thread: putMVar sync () Is this normal or have I missed the `waitOnThreadId` function? Thanks for all the comments received on this thread, Olivier. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] getting output from shell commands
Hi, I would like to be able to run a shell command like curl and process the output in my Haskell program, but I couldn't find anything helpful about it. Something like main = do args - getArgs inp - exec curl args putStrLn (processInput inp) would be very helpful. Regards Philip ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] runInteractiveCommand: program ends before writing or reading all the output
Hello Olivier, Thursday, May 15, 2008, 11:06:19 PM, you wrote: As I could not find a function to wait on a ThreadId I used a MVar to synchronize both threads. Is this normal or have I missed the `waitOnThreadId` function? yes, it's common idiom -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] getting output from shell commands
Hello, I would like to be able to run a shell command like curl and process the output in my Haskell program, but I couldn't find anything helpful about it. Try looking in System.Process. runInteractiveProcess should work for you. -Jeff --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] getting output from shell commands
Hi Philip, I just asked a question to the list about using runInteractiveCommand. You may find the code useful but will need to either remove the forkIO instruction or synchronize the two threads using a MVar to avoid the concurrency problem I had. You'll find the thread here: http://www.haskell.org/pipermail/haskell-cafe/2008-May/042975.html Regards, Olivier. On Thu, May 15, 2008 at 3:18 PM, Philip Müller [EMAIL PROTECTED] wrote: Hi, I would like to be able to run a shell command like curl and process the output in my Haskell program, but I couldn't find anything helpful about it. Something like main = do args - getArgs inp - exec curl args putStrLn (processInput inp) would be very helpful. Regards Philip ___ 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] Write Haskell as fast as C. [Was: Re: GHC predictability]
Side point: Is the name go part of the idiom you mentioned? I sometimes use the same practise but usually just calls the worker the same as the real function with an added prime ('). I like to use go or the name of the function with _ prepended. For threading state type things outside of a monad, I generally use numbers let state2 = f state1. I know the prime is conventional, but it's such a tiny mark on a symbol that's otherwise identical I tend to lose it accidentally, leading to type errors for the first, or either bus errors or silently doing the wrong thing for the second (fortunately ghc's unused variable check has always caught that, but I did spend some time thinking the bus error was c++'s fault...). If the accumulator function has the same signature as the wrapper you can also get silently wrong behaviour by recursing to the wrong function. It's probably harder to do that with 'go' than with a prime. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Two-iteration optimisation (was: GHC Predictability)
Yitzchak Gale wrote: And of course, you wouldn't want that: f xs = xs : map expensiveCalculation xs Please don't fuse those two loops into one. ...doesn't type check. Did you mean (++)? In the case of mean, the outer function in question is /, and that is a good candidate for fusion because it is strict in both arguments. I think Don is right. There is a lot of room for expanding the scope of fusion, but it needs to be done one function at a time until our strictness analysis gets better. Mmm, strictnes analysis. That sounds hard... In the general case, I like the way things work now. The original complaint about unpredictability is, in my opinion, a bug in the documentation. This is yet another concept whose basics need to be made much more accessible to newbies. ...which is really the point I was trying to get across, yes. :-) Certainly there are experts [like Don] who seemingly have no trouble knocking out blindingly fast Haskell code. The problem is that only the halowed experts can do this; it's currently rather inaccessible to beginners and intermediates. For example, back when I really *was* a beginner, I found several fleeting references to laziness can be bad sometimes, but I couldn't find anywhere that explains *why*. The concept that laziness could be something you *don't* want seemed highly counter-intuitive. [After all, laziness is this wonderful thing that stops you doing extra work you don't need to!] Indeed, it wasn't until I wrote a Haskell interpretter that I discovered the [main] problem - huge unevaluated expressions being needlessly dragged around. The fact that laziness is bad sometimes is a pretty basic piece of information for anybody remotely serious about performance programming to be made aware of. I think the information is out there, it's just not tefficially findable right now. I'm not 100% sure what the best way to improve this situation would be, but I think it involves somebody somewhere sitting down to write a single, coherant account from beginning to end explaining what the issues are, in language that people who aren't compiler designers can understand. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Write Haskell as fast as C. [Was: Re: GHC predictability]
Mattias Bengtsson wrote: A good read. With Don, it usually is. ;-) Side point: Is the name go part of the idiom you mentioned? I sometimes use the same practise but usually just calls the worker the same as the real function with an added prime ('). I usually use work. Same difference. :-) From what I can tell, the Prelude implementation in the Haskell Report uses primes on the function names [in the tiny number of cases where a worker function is actually required]. Each to their own... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re[2]: [Haskell-cafe] Fun with Darcs
On Thu, 2008-05-15 at 01:01 +0400, Bulat Ziganshin wrote: Hello Andrew, Thursday, May 15, 2008, 12:49:32 AM, you wrote: touch. Now, let's see what this IDE actually looks li-- oh you have GOT to be KIDDING me! It can't find the right GTK DLL?!? gtk2hs includes *developer* gtk2 environment. Which includes all the runtime dlls. while it should work fine (as far as it's in your path), you may try to install *runtime* gtk2 environment from http://sourceforge.net/project/showfiles.php?group_id=71914package_id=255391 I would not recommend that. I'd use the dlls that come with gtk2hs. Of course if you're deploying a Windows program that uses gtk2hs then using just the runtime dlls is just the right thing to do. Though for that case we provide the runtime dlls: http://haskell.org/gtk2hs/win32/ As an example, here's an installer for a standalone prog that uses gtk2hs but doesn't need ghc or gtk2hs to be installed already: http://haskell.org/~duncan/gtk2hs/LSystemSetup.exe Duncan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fun with Darcs
On Wed, 2008-05-14 at 21:49 +0100, Andrew Coppin wrote: At this point, my best guess is that the unofficial Gtk2hs binary is broken somehow. [Although I don't recall hearing anybody yelling about it...] Maybe tomorrow I'll try again on my other box that has an older GHC on it and see how that goes. For tonight, I'm just too frustrated to continue. Is this the unofficial Gtk2Hs installer you were using? http://haskell.org/~duncan/gtk2hs/gtk2hs-0.9.12.1.exe I've been told it works ok. If you've only just installed it then you do need to start a new command shell because existing open shells do not pick up the change to the environment variables. You can double check that Gtk2Hs installed ok by cd'ing to one of the demo directories and using ghc --make to build a demo. If then demo .exe runs ok then the dlls are on the %PATH%. If that fails, you can double check your user %PATH% and make sure it does have an entry that points to the Gtk2Hs/bin dir. The Gtk2Hs installer only sets the %PATH% for the user that ran the installer, not globally for every user. I hope you can get it working. Duncan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] runInteractiveCommand: program ends before writing or reading all the output
On Thu, 2008-05-15 at 13:40 -0400, Olivier Boudry wrote: Hi all, It's the first time I use the runInteractiveCommand and I was probably bitten by laziness. Yes. I think Philip diagnosed the problem correctly. As an example let me show you as an example how we use it in Cabal: rawSystemStdout :: Verbosity - FilePath - [String] - IO String rawSystemStdout verbosity path args = do Exception.bracket (runInteractiveProcess path args Nothing Nothing) (\(inh,outh,errh,_) - hClose inh hClose outh hClose errh) $ \(_,outh,errh,pid) - do -- We want to process the output as text. hSetBinaryMode outh False -- fork off a thread to pull on (and discard) the stderr -- so if the process writes to stderr we do not block. -- NB. do the hGetContents synchronously, otherwise the outer -- bracket can exit before this thread has run, and hGetContents -- will fail. err - hGetContents errh forkIO $ do evaluate (length err); return () -- wait for all the output output - hGetContents outh evaluate (length output) -- wait for the program to terminate exitcode - waitForProcess pid -- on failure, throw the exit code as an exception unless (exitCode == ExitSuccess) $ exitWith exitCode return (output, exitcode) So as you can see there are two subtleties. One is the issue that we have to make sure we get all the output before we wait for the program to finish. Using evaluate is the trick there. The other is that we also have to pull on the stderr of the process. Otherwise the process may be trying to output to stderr but if the pipe buffer fills up then writing to stderr will block and so it will not be able to continue writing to stdout we'll have deadlocked the process. So we have to forkIO a thread to pull on stderr. This is one reason that runInteractiveProcess is hard to use and especially hard to use portably due to the use of preemptable threads. It would be possible to do without threads if we used non-blocking IO and interleaved between reading from stdout and stderr. Duncan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Richer (than ascii) notation for haskell source?
On 15 May 2008, at 8:33 pm, Yitzchak Gale wrote: The point is that it is always best to keep language syntax as simple as possible, for many reasons. In the case of Unicode, that means staying as close as possible to the spirit of Unicode and minimizing our own ad hoc rules. In particular, Unicode has explicit guidance about what an identifier should be, in UAX#31: http://www.unicode.org/reports/tr31/tr31-9.html I've only recently started slogging my way through the capital-city-telephone-book-size Unicode 5.0 book. (I was tolerably current to 4.0) Imagine my stress levels on discovering that Unicode 5.1 is already out, with another 1,624 newly encoded characters, including a capital letter version of ß. It is deeply ironic that one of the things that keeps changing is the stability policy. Another of the things that has changed is UAX#31. Adding one more keyword is way simpler than adding a bunch of complex rules to the lexer. Um, there's no way a Haskell lexer is going to comply with the Unicode rules without a fair bit of complexity. The basic idea is simply id startid continue*, but there are rules about when ZWJ and ZWNJ are allowed. The real issue here is Unicode compliance, and the Unicode rules say that a mixture of scripts is OK. Er, it's not actually that simple. They do recommend that the scripts in table 4 _not_ be allowed in identifiers, so if you fancied writing some of your identifiers in Shavian, you may or may not be out of luck. (Just why a Coptic priest who is also a coder should be discouraged from using the Coptic script in his programs escapes me.) A lot less moving parts to break. Especially if those lexer rules are not so consistent with built-in Unicode concepts such as letter and symbol, glyph direction, etc. UAX#31 definitely allows identifiers with any mixture of left to right and right to left characters. The *intent* is that anything even remotely reasonable should be accepted, and should keep on being accepted, but of course the devil is in the details. So I think the best and simplest idea is to make the letter lambda a keyword. The lambda that people actually *want* in Haskell is in fact the mathematical small letter lambda, not the Greek letter. UAX#31 explicitly envisages mathematically oriented programming languages that make distinctive use of the Mathematical Alphanumeric Symbols. I don't think there can be much argument about this being the right way to encode the symbol used in typeset versions of Haskell. There are three arguments against using it routinely: (a) It is outside the 16-bit range that Java is happy with, making it hard to write Haskell tools in Java. But then, about 40% of the characters in Unicode are now outside the 16-bit range that Java is comfortable with, which is just too bad for Java. Haskell tools should be written in Haskell, and should cope with 20-bit characters. (I used to say 21- bit, but Unicode 5 promises never to go beyond 16 planes.) (b) It is outside the range of characters currently available in fonts. A character you cannot type or see isn't much use. Implementations *will* catch up, but what do we do now? (c) People *can* type a Greek small letter now, and will not be interested in making fine distinctions between characters that look pretty much the same. So people will *expect* the Greek letter to work, even if a pedant like me says it's the wrong character. Of course, we could always take an upside down lambda and put some bars through it and use ¥ for lambda. (Pop quiz: why would some people not be surprised to see this instead of \ ?) [It's a joke.] All of this seems to leave Greek small letter lambda as a keyword as being the simplest solution, but it's easy to predict that it will cause confusion. True, you need a space after it then. You already need spaces between the variables after the lambda, so anyway you might say that would be more consistent. Who says there is more than one variable? \(x,y,z)- doesn't have any spaces. \x - \y - \z - needs spaces, but that's because -\ is a single token, not because of the identifiers. -- I don't want to discuss evidence. -- Richard Dawkins, in an interview with Rupert Sheldrake. (Fortean times 232, p55.) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] bottomless Top?
On 15 May 2008, at 4:29 AM, Conor McBride wrote: Replying slap-foreheadedly to own post... On 15 May 2008, at 11:56, Conor McBride wrote: Folks I'm also wondering whether it makes sense to have a bottomless Top type, with constructor _ and lazy pattern _ (with (undefined :: Top) equal to _). Then the constant-time shape operator makes the same sort of sense as the constant-time inflate :: Functor f = f Zero - f a We've got it already. data One would do, with smart constructor only :: One only = undefined As I've mentioned before, my favorite data type newtype One = One One does the same, and stays in Haskell 98. (And has the same weakness to seq: (`seq` ()) is perfectly strict (it's const undefined)). jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] runInteractiveCommand: program ends before writing or reading all the output
On Thu, May 15, 2008 at 6:23 PM, Duncan Coutts [EMAIL PROTECTED] wrote: On Thu, 2008-05-15 at 13:40 -0400, Olivier Boudry wrote: As an example let me show you as an example how we use it in Cabal: Hi Duncan, I tried to place a length text `seq` before the mapM_ writeExport to force the process output to be read but the result was even worst (only one line printed). Apparently withtout the `evaluate` function it causes more troubles than it solves. The example you provided is really helpful. I learned a lot reading it. Thanks, Olivier. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] bottomless Top?
On 16 May 2008, at 01:13, Jonathan Cast wrote: On 15 May 2008, at 4:29 AM, Conor McBride wrote: Replying slap-foreheadedly to own post... On 15 May 2008, at 11:56, Conor McBride wrote: Folks I'm also wondering whether it makes sense to have a bottomless Top type, with constructor _ and lazy pattern _ (with (undefined :: Top) equal to _). Then the constant-time shape operator makes the same sort of sense as the constant-time inflate :: Functor f = f Zero - f a We've got it already. data One would do, with smart constructor only :: One only = undefined As I've mentioned before, my favorite data type newtype One = One One does the same, and stays in Haskell 98. That's rather fun. On the face of it, it looks peculiar that *Top case undefined of One _ - True True until you put your newtype constructor sunglasses on. Funny that newtype constructors really are like id until you fmap them. Or is that optimized away these days? (And has the same weakness to seq: (`seq` ()) is perfectly strict (it's const undefined)). Oh b! I'd forgotten that seq lets you look at an undefined thing just enough to go wrong. It'd be lovely to have proper unit and product, with their eta-laws, compiling pattern matching to projection. Was it so bad to distingush the value types at which seq could be applied? Meanwhile, the game's up for the unsafeCoerce dodge: *Top shape ['m', undefined, 'o'] [(),*** Exception: Prelude.undefined I knew it was too good to be true. Like Randy Pollack says, the best thing about working in strongly normalizing languages is not having to normalize things. Loose morals are neither fast nor correct. I'd better crawl back under my rock. All the best Conor ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Two-iteration optimisation (was: GHC Predictability)
On Thu, May 15, 2008 at 8:45 PM, Andrew Coppin [EMAIL PROTECTED] wrote: Yitzchak Gale wrote: And of course, you wouldn't want that: f xs = xs : map expensiveCalculation xs Please don't fuse those two loops into one. ...doesn't type check. Did you mean (++)? Hmm? While the name might be misleading... expensiveCalculation = (:[]) Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe