Search posterous

Search all posts and users. Type a name, type a favorite song title, whatever! See what comes up.
  

More posterous blogs











More recommended blogs »

Here are posterous posts filed under haskell...

chak says...

Four years ago the Haskell' Committee was assembled, charged with the task to produce a new revision of the Haskell language standard (aka Haskell 98). There was a lot of enthusiasm and many wild ideas in the beginning, but it turned out that it was hard to agree on the scope of changes and that it was very hard to find a person willing to shoulder the rather large editorial burden that a major revision of Haskell entails.

The Committee finally decided that our only realistic chance of making progress was to break the mammoth task into smaller chunks. More concretely, we decided to evolve the language in small increments with a release every year, while rotating the committee on an annual basis to avoid burn out.[1] Whether this fine-grained evolutionary approach to language design will be successful in the long run remains to be seen. Nevertheless, the new approach helped us to make progress and to agree on a revision for this year: behold Haskell 2010!

[1] Details about The Haskell Prime Process

Filed under: haskell

Sam says...

I've been using, researching and evaluating the functional programming paradigm over the last few months. I've had my eye on several languages; Haskell and Scala in particular.

Originally, I was fond of Scala as it embraced the OOP paradigm that I've come to know and love. It fuses OOP and function programming. I thought this was a good thing. Then came along Haskell.

Haskell is a beautiful langauge. I've only been using it for around a month, so I'm not in a great position to talk about it in-depth. Haskell is the most pure functional language I've come across. You can't even access IO without explicitly declaring it and adopting a different syntax. Haskell "taints" any function that uses IO; if a function returns a string from a file, it will return IO String, and not String.

Using Haskell made me see how strange of a mix Scala is. The whole objective of functional programming is to have a language that doesn't have side effects. How can you mix OOP, which encapsulates an object and provides data and methods to manipulate that data, and FP, which should be side-effect free; they just don't go hand-in-hand.

The idea of "side-effect free" programming can seem odd at first. Especially when you've been using procedural and object-oriented languages for years. But it becomes obvious why it exists when your code base starts getting larger. It becomes more modular, predictable and obvious.

Haskell really is a great language. I strongly suggest anyone to go and start using it. Even if you never use it for a real project, the principles you learn from it are priceless. Using Haskell has even changed the way I code in other languages, such as Ruby.

Filed under: haskell

Sam says...

Function Composition:

In haskell, it's defined as:

As you can see, there is a lambda in the definition. An obvious use for function composition then is for the map function. Often there are times when you need to apply two functions for every element in a list, and this is pretty much made for that occasion.

It also has a simpler use: getting rid of that jungle of parenthesis. These two are identical:

The only reason that function composition can be implemented (and in such a beautiful way) is through high-order functions. They are the life and soul of Haskell. For those of you that don't know; a high-order function is any function that passes a function as an argument and/or returns function.

One sign that I may be embracing Haskell a little too much: I'm beginning to think being lazy isn't a bad thing.

Filed under: haskell

Sam says...

I implemented a way to count the number of entries in an abstract file system in Haskell.

Pattern matching is a super-powerful feature. I think it reads naturally.

Filed under: haskell

chak says...

If you are interested in Haskell generally or the Glasgow Haskell Compiler (GHC) in particular, you may want to have a look at the latest issue of the biannual GHC status updates.  It includes a summary of our recent progress in the Data Parallel Haskell project.

Filed under: haskell

pepe says...

Call traces are a recurrent topic in the Haskell community. Nearly every programming language out there has this feature, except Haskell. For an imperative language providing stack traces is easy, since the runtime stack contains all the information needed, and it can be retrieved essentially for free. But in a lazy language the stack does not contain call frames, and hence providing a "stack trace" is a much more involved task. As existing efforts we can cite the -xc flag of the GHC profiling runtime, which provides a stack trace based on cost centers; and the GHCi debugger :trace command which records a lazy call trace. There is also the Hat tool which is capable of providing a post-mortem stack trace via a program transformation, but I don't know if you can make Hat work nowadays. And the not yet released tool for GHC presented by Tristan Allwood in the Haskell Symposium(video). With exception of the latter, which is not yet available, I believe that all these options are not really solving the lack of stack traces in practice.

While working on the control-monad-exception and by suggestion of Jeff Heard I have been looking at providing exception call traces. That is, making a call trace available to an exception handler. This can be very useful to give more detailed error messages which help to diagnose a problem in our code. For instance, recall the example in my previous post.

 data ProcessError = NotThreeLines String   deriving (Show, Typeable)
 instance E.Exception ProcessError
 process :: FilePath -> AttemptT IO Int
 process filePath =
       contents <- A.readFile filePath
       case lines contents of
           [num1S, opS, num2S] -> do
               num1 <- A.read num1S
               op   <- A.read opS
               num2 <- A.read num2S
               return $ toFunc op num1 num2
           _ -> Failure $ NotThreeLines contents

A.read is a custom version of read which throws an exception if Prelude.read fails to read its argument. There are three different source code locations in which A.read may fail in the body of process. Getting a ReadFail exception is not going to tell you *which* read attempt failed, in the same way that a "head of empty list" error does not tell you which call to head of all the calls to head in your program failed. With support for exception call traces, you could get an error message for this exception that looks like this:

error: ReadFail: could not read the String ....
  in Main.hs: line 27, col 20
  in ...
  in ...
  in Process.hs: line 12, col 15

This is not possible right now. None of the libraries for exceptions in Hackage support this kind of call traces. Admittedly, the situation is not as bad as the "head of empty list" case, because if you are using a version of head that throws an exception, chances are high that the exception will be captured close enough to the call site that it is clear where the error is coming from. But still, anything below this level of error reporting is substandard in a modern programming language.

In this post I show how a standard Error monad can be extended to carry call traces. An error monad in Haskell can be implemented by the Either datatype, a suitable Monad instance, and a pair of throw and catch functions. The Left constructor denotes an exception, defined here as the SomeException type in ControlException, and the Right constructor denotes a succesful computation. Omitting unessential cruft the code looks like:

 type ErrorM a = Either SomeException a

 throw :: e -> ErrorM a
 throw = Left

 instance Monad (Either e) where
   return = Right
   Left  e >>= _ = Left e
   Right v >>= f = f v

 catch :: Exception e => ErrorM a -> (e -> ErrorM a) -> ErrorM a
 catch (Right v) _ = Right v
 catch (Left e) h = ...

Nothing surprising here. I omitted part of the implementation of catch because it is slightly more involved due to the existential machinery that makes SomeException work.

We want to extend this interface with a function catchWithCallTrace which provides access to the call trace. Something with a signature

 catchWithCallTrace :: Exception e => ErrorM a -> (e -> [SrcLoc] -> ErrorM a) -> ErrorM a
 type SrcLoc = String

where SrcLoc is some abstract datatype for source code locations. In this case a simple String suffices.
To generate this call trace, the first step is to extend our ErrorM monad to keep a list of source code locations in the Left constructor.

 type ErrorM a = Either (SomeException, [SrcLoc]) a

The next step is modify the definition of bind so that it inserts the current source code location in the call trace whenever it spots an exception.

 Left (e, trace) >>= f = Left (e, <currentloc> : trace)

In this way whenever the exception reaches a handler, it will find a list of SrcLocs starting from the throw site all the way up to the handler site stored in the computation. This constitutes a monadic call trace, which due to the order of evaluation imposed by the Either monad, resembles very closely a stack trace from an imperative language. This is great, because that is exactly the kind of call trace that makes sense to the programmer. I have been testing the library with a small personal project involving a CGI applet and a database, and the capture below shows the kind of error output that my CGI applet provides.

 

The implementation of catchWithCallTrace now is straightforward. 

 catchWithCallTrace (Left (exception, trace)) h = h exception trace

The above line is pseudocode since it omits the handling of the existential stuff for SomeException, but it conveys the idea.
All what is missing now is to turn the equation for (Left e >>= f) above into real Haskell. Those source code locations must be made available to (>>=). This is not possible in the standard definition of (>>=), so we extend the Monad type class with a bindWithSrcLoc method, polluting its categorical elegance with the concerns of mundane coders.

 class Monad where
   ...
   bindWithSrcLoc :: SrcLoc -> m a -> (a -> m b) -> m b
   bindWithSrcLoc _ = (>>=)

This is a conservative extension which breaks no existing code and has no performance penalty. There is a default implementation which ignores the source location and calls bind, and there should be no performance penalty at all for using bindWithSrcLoc in a regular monad which does nothing with src locs, if we can trust GHC to inline the body of (>>=) in the default definition.

For the ErrorM monad we give bindWithSrcLoc a different implementation:

 instance Monad ErrorM where
   ...
   bindWithSrcLoc srcloc (Left (e, trace)) _ = Left (e, srcloc:trace)
   bindWithSrcLoc srcloc (Right x) f = f x

That is all what is needed to provide monadic call traces. In order to make programming with bindWithSrcLoc feasible, Haskell compilers can desugar do-notation using the bindWithSrcLoc variant, providing accurate source code locations which are available at "desugaring time". Yes, this means that do-notation stops being mere syntactic sugar to become something more, but I perhaps it is a small price to pay if we gain monadic call traces in the process? Once there is support for this in the compiler, any monad can implement this interface and provide this facility, including the IO monad, the ErrorT monad transformer from the mtl package, and any other error handling monad.

To wrap up this post, I am making available an experimental implementation of monadic call traces with the 0.5 release of control-monad-exception. Obviously I can't just extend the Monad class in a package, so the mechanism used in this release is not as elegant as the one presented here. It uses a MonadLoc class to deal with source code locations and includes the MonadLoc preprocessor, a tool based on haskell-src-exts (thanks Niklas for such an awesome library, the entire code for the preprocessor fits in a few lines of haskell) which makes the source code locations happen in the right places. When, if ever, the Monad class is extended to provide source locations, the MonadLoc preprocessor will no longer be needed. But in order to get monadic stack traces now, all you need to do is to use the Control.Monad.Exception.EMT monad in you code and insert the following pragma at the top of your files:

{-# OPTIONS_GHC -F -pgmF MonadLoc #-}

I should also mention that nothing in the monadloc package is specific to control-monad-exception. Any other monad can implement the MonadLoc type class and benefit from the MonadLoc preprocessor to provide monadic call traces.

Enjoy your Haskell monadic call traces!

Filed under: haskell

chak says...

After much digging through otool output and tracing Haskell code with dtrace, log messages, and gdb, I finally found the cause of the SIGBUS errors with ghci on Snow Leopard. At the end, only a tiny change was required[1]: the homegrown dynamic linker of ghci had simply ignored a relocation type that ld on Snow Leopard chose to use.

What this really shows again is that re-implementing parts of basic infrastructure in an ad hoc manner always comes back to bite you. Such infrastructure is usually full of low-level, platform-dependent details, which you are bound to get wrong once in a while and then it can be rather involved to find the problem. In this case, the relocation of the memory access of a bit of C code in GMP, reading a global variable, went wrong. As a result, the wrong memory location was accessed, which happened to contain a NULL pointer. Upon dereferencing the NULL, the program crashed.

All of this was further obscured by the fact that the homegrown linker approach of ghci implies that we have two copies of the basic libraries in memory and in use at the same time. One copy has been statically linked with the ghc executable and the second copy is dynamically loaded by ghci. The relocation in the statically linked copy was perfectly fine, but the relocation in the dynamically loaded one was broken.

[1] http://www.haskell.org/pipermail/cvs-ghc/2009-October/050863.html

Filed under: haskell

pepe says...

Yesterday Michael Snoyberg blogged a tutorial about his Attempt package for Haskell error handling. This inspired me to port his example to my control-monad-exception library and see how well it works.The main difference between the two libraries is that Attempt provides extensible exceptions which are not explicit whereas control-monad-exception' exceptions are explicit and checked by the type system a la java and .NET. Under the hood they are very similar, Both are monads based on a datatype isomorphic to Either instantiated with extensible exceptions, but control-monad-exception has some extra oomph to make the typechecker understand exception handling. Michael dismisses control-monad-exception arguing that explicit exceptions produce "insanely long type signatures". Since I don't agree on that, I hope to support my point with this blog post.

His tutorial introduces an example about text processing to illustrate the use of Attempt: you want to parse text files which should contain three lines, each line containing an arithmetic expression of the form line  ::= <num> <op> <num>. Easy enough, the following Haskell program (copied from his blog) does the job:

> process1 :: FilePath -> IO Int
> process1 filePath = do
>   contents <- readFile filePath -- IO may fail for some reason
>   let [num1S, opS, num2S] = lines contents -- maybe there aren't 3 lines?
>       num1 = read num1S -- read might fail
>       op   = read opS   -- read might fail
>       num2 = read num2S -- read might fail
>   return $ toFunc op num1 num2

Michael explains very clearly why each of those lines may fail and then goes on to replace the unsafe functions by their Attempt equivalents:

  • read is a partial function; it is replaced by a total function in an Attempt monad read' :: AttemptMonad m => String -> m a  
  • readFile is an IO function which can take an exception. It is replaced by a version in the Attempt monad.  
  • the pattern matching is replaced by an assertion; I didn't understand the motivation and think the resulting code is a bit more difficult to understand so I will skip this part.

You do that and the result is the following code.

> data ProcessError = NotThreeLines String   deriving (Show, Typeable)
> instance E.Exception ProcessError
> process :: FilePath -> AttemptT IO Int
> process filePath =
>       contents <- A-readFile filePath
>       case lines contents of
>           [num1S, opS, num2S] -> do
>               num1 <- A.read num1S
>               op   <- A.read opS
>               num2 <- A.read num2S
>               return $ toFunc op num1 num2
>           _ -> Failure $ NotThreeLines contents

The resulting code is safe. Running it produces either a Success or a Failure, but can never end with a runtime exception. Now, let's look at doing the same with control-monad-exception (abbreviated c-m-e from here). First, we need to define safe versions of read and readFile. The c-m-e library provides a type class MonadThrow for computations which may raise an exception.

> safeRead :: (MonadThrow ReadException m, Read a) => String -> m a
> safeRead s = case .. of
>               [x] -> return x
>                _  -> throw $ ReadException s

I omitted the implementation since it is fairly routine and could live in a library. The interesting thing is that the inferred type signature documents the fact that a ReadException can be thrown. Compare it with the type signature of the version of read in the Attempt library:

> attempRead :: (MonadAttempt m, Read a) => String -> m a

The c-m-e version is not really that much longer after all. The corresponding c-m-e safe version for readFile has the type signature

> readFile :: (MonadIO m, MonadThrow IOException m) => FilePath -> m String

which again is not too bad. Note also that these functions are not defined in any library, since the c-m-e package currently provides only the exception monads and some support combinators. More on that now.

The nice thing at this point is that we haven't commited to a particular monad. c-m-e provides a monad transformer EMT which can be used for checked, explicit exceptions, but there are also MonadThrow instances for IO and Either which can use the error handling capabilities of those monads as well - and yes, those MonadThrow constraints will go away and you will be back in the world of unchecked and unexplicit exceptions, if that's what you want-. A MonadThrow instance for Attempt could be easily provided too, and in that way we could have all these safe functions in an independent package which can work with any error handling monad, be it attempt, c-m-e, explicit-exceptions or the IO monad. Please, we must have this.

Ok, enough rambling, back to the example. As you can imagine, the code for the process function is going to be exactly the same as before, modulo the function names. Except that now the type signature is not fixed to any particular monad:

> process :: (MonadIO m, MonadThrow IOException m, MonadThrow ReadException m)
>              => FilePath -> m Int

This is an inferred type signature and one which you would not write yourself normally, as in general you would be working inside a particular monad, not just any monad m. If this monad happens to be the Attempt monad, you would obtain exactly the type signature that we had above:

> process :: FilePath -> AttemptT IO Int

Which is appreciablily shorter. This tells you that process is a computation which can be run and produce either an Int or fail with an (undocumented) error. On the other hand, if you use EMT from the c-m-e package, the following inferred short-enough type signature tells you

> process :: (Throws IOException l, Throws ReadException l)
>              => FilePath -> EMT l IO Int

that process is a computation which can be run and may fail with an IOException or a ReadException. We can go ahead and define a new version of process which handles the IOException:

> process1 s = process s `catch` \(e::IOException) -> return (-1)

And now the compiler *knows* that process1 has the type:

> process1 :: Throws ReadException l => FilePath -> EMT l IO Int

as expected. This is the main idea behind the c-m-e library: using the typechecker to track which exceptions have not been caught yet. Type signatures should not grow unwieldly long, unless your code is sloppy and has lots of unhandled exceptions around.

I am going to leave it at here. Michael's tutorial goes on and wraps the exceptions into the domain exceptions BadIntException and BadOpException, which should always be done.

The c-m-e library provides also other niceties such as stack traces and selectively unchecked exceptions. I encourage you to look at the documentation for the package if you are interested on doing proper error handling in Haskell.

Filed under: haskell

chak says...

Don Stewart summarised the state of play of parallel programming in Haskell at "ACM Reflections | Projections 2009". He covers strategies, Concurrent Haskell, STM, and Data Parallel Haskell: http://donsbot.wordpress.com/2009/10/17/multicore-haskell-now-acm-reflections-projections-2009/

Filed under: haskell

chak says...

Don argues in favour of domain-specific languages for high-performance computing. Not surprisingly, he suggests that Haskell is well suited as a host for realising such domain-specific languages as embedded languages: http://donsbot.wordpress.com/2009/10/16/lacss-2009-domain-specific-languages-and-haskell/

Filed under: haskell