RE: Application letters at the Haskell workshop: suggestion
Thanks, that's very valuable information. It's hard to appreciate the relative utility (as you can see :-)) of different experimental features. It's also confusing that things like exceptions, concurrency, and FFI are labeled 'experimental'. They're so (IMHO) crucial that I find myself saying, "Okay, if exceptions are 'experimental', what other really important things might I be missing by not being familiar with all the experimental extensions?" Thanks for clearing that up somewhat. On a tenuously related note, I should mention that so many Haskell examples focus on things which fit easily into a functional mold (factorial, etc.) that I did not actually have the faintest idea how to create a real and useful Haskell program until I saw the code for Simon Marlow's web server. The snippets on Doug Bagley's Computer Language Shootout were also helpful. It's also very difficult to find examples which demonstrate the use of experimental features. I mention this only because your report below of what features you use daily provides a useful point of reference for people wondering what actually goes into a non-trivial Haskell application. Bryn
I consider myself a fairly hardcore Haskell user (I used to be a language designer and compiler/library developer but now I work on another language and write my tools in Haskell and perl). Despite this, I don't think I use any of the features you list (I guess I'm suggesting that these might not be the most important to you either).
I do use the IO monad, IORefs (sparingly), constructor classes, lots of libraries, the foreign function interface (lets you call C and C++), parser generators (happy) and parser combinators, exception handling and concurrency (even just the lame non-preemptive version that Hugs provides).
Of course, this partly reflects the kinds of programs I write and, to some extent, my being comfortable with the features and libraries I know and not having time to really explore what I can do with the other features.
-- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/
brk@jenkon.com wrote:
Thanks, that's very valuable information. It's hard to appreciate the relative utility (as you can see :-)) of different experimental features.
It's also confusing that things like exceptions, concurrency, and FFI are labeled 'experimental'. They're so (IMHO) crucial that I find myself saying, "Okay, if exceptions are 'experimental', what other really important things might I be missing by not being familiar with all the experimental extensions?" Thanks for clearing that up somewhat.
I have been writing substantial Haskell programs and I use *NO* experimental features. What I'm currently working on is over 20000 lines of Haskell 98. No extensions whatsoever. (It even compiles and runs with all available Haskell implementations.) Granted, I write mostly compiler like programs (files in, files out), but there is still a lot you can do in Haskell just as it is. Sometimes it might require bending slightly backwards to get it done, though. -- Lennart PS. OK, a small confession, that program contains one unsafePerformIO for performance reasons. It works fine without it, but 5% slower.
Lennart Augustsson wrote:
I have been writing substantial Haskell programs and I use *NO* experimental features. What I'm currently working on is over 20000 lines of Haskell 98. No extensions whatsoever. (It even compiles and runs with all available Haskell implementations.) Granted, I write mostly compiler like programs (files in, files out), but there is still a lot you can do in Haskell just as it is. Sometimes it might require bending slightly backwards to get it done, though.
Well, that's nothing! I have been writing substantial ANSI C programs and I use *NO* experimental features. What I'm currently working on is over 20000 lines of ANSI C. No extensions whatsoever. (It even compiles and runs with all available C implementations.) Granted, I write mostly compiler like programs (files in, files out), but there is still a lot you can do in ANSI C just as it is. Sometimes it might require bending slightly backwards to get it done, though. ;-) --Jeff
brk@jenkon.com wrote,
Thanks, that's very valuable information. It's hard to appreciate the relative utility (as you can see :-)) of different experimental features.
It's also confusing that things like exceptions, concurrency, and FFI are labeled 'experimental'. They're so (IMHO) crucial that I find myself saying, "Okay, if exceptions are 'experimental', what other really important things might I be missing by not being familiar with all the experimental extensions?" Thanks for clearing that up somewhat.
Maybe it should be clarified that there are exceptions in H98, but *only* in the IO monad. What the extension is about are exceptions in pure functions. As for the FFI and concurrency, I agree with you, but these are also the two extensions of which it is very clear how to do them by now and it is more a matter of getting all implementations in sync. Languages like Perl and Python don't have this problem. There is just one implementation and that defines the language. Otherwise, I can assure you, Haskell has a rather complete feature set and is ready for serious use. Cheers, Manuel [1] I know that this is not entirely true for Python, but the net effect is the same.
"Manuel M. T. Chakravarty" wrote:
Maybe it should be clarified that there are exceptions in H98, but *only* in the IO monad. What the extension is about are exceptions in pure functions.
Further clarification: the extension allows you to _raise_ exceptions in pure functions, but you may only catch them in the IO monad. This asymmetry is very important for Haskell, since otherwise evaluation order would be observable. This would break many important equalities and render almost any optimizations unsafe (i.e., GHC would be crippled). ML allows one to catch exceptions in pure functions with impunity, and can do so because evaluation order is fixed. The story is similar for imperative languages. A further extension to this exceptions mechanism allows one to catch asynchronous exceptions (e.g., interrupts or UNIX signals) in the IO monad, and to signal (or "raise an asynchronous exception in") other threads. There are also scope-based operators "block" and "unblock" which, given a computation, perform it with asynchronous exceptions blocked/unblocked respectively. They may be nested arbitrarily. I believe GHC is the only system with this extension implemented thus far, but there are rumours of Hugs not being far behind (I'm looking at you, Alastair David :-) The exceptions mechanisms would certainly benefit from an addendum. Cheers, Andy -- Andy Moran Ph. (503) 526 3472 Galois Connections Inc. Fax. (503) 350 0833 3875 SW Hall Blvd. http://www.galconn.com Beaverton, OR 97005 moran@galconn.com
On Fri, 14 Sep 2001 moran@galconn.com wrote: (snip)
Further clarification: the extension allows you to _raise_ exceptions in pure functions, but you may only catch them in the IO monad.
This asymmetry is very important for Haskell, since otherwise evaluation order would be observable. This would break many important equalities and render almost any optimizations unsafe (i.e., GHC would be crippled). ML allows one to catch exceptions in pure functions with impunity, and can do so because evaluation order is fixed. The story is similar for imperative languages. (snip)
For the sort of exception where the function you're calling either returns successfully or throws an exception, I'm not sure why things can't be done entirely referentially transparently. One would do it in just the same way that something might return a 'Succeeded a' or 'Exception String' or something as aspects of an algebraic data type. The function, whenever it does something that might cause an exception, if it gets a 'Succeeded a' returned it goes ahead and returns something based on the a, or else it returns the Exception String, except if there's a 'catch' which specifies some other value to return if there was an exception. Basically, such simple exceptions can have a 'try', 'catch' construct simply being syntactic sugar around existing Haskell using algebraic types, pattern matching and 'if' statements, so I don't see why monads need to be brought in. Evaluation is done exactly as usual - when you decide to do something predicated on whether or not there was an exception thrown, we evaluate enough to find out if an error condition happened. However, there is a lot I don't know about Haskell! I assume you're talking about some more exciting sort of exception, like things with multiple threads or something, and I'm thinking of something more simplistic (but adequate for my immediate needs, which are currently being served with lots of ifs and Maybes!). -- Mark
On Fri, 14 Sep 2001, Mark Carroll wrote: (snip)
simplistic (but adequate for my immediate needs, which are currently being served with lots of ifs and Maybes!).
Oh - and I should add, lots of two-tuple return values which are basically of the form (Maybe a, error details). ): -- Mark
participants (6)
-
brk@jenkon.com -
Jeffrey R Lewis -
Lennart Augustsson -
Manuel M. T. Chakravarty -
Mark Carroll -
moran@galconn.com