Jun 182013
 

Chatting with merijn on #haskell, I realized I have a file server running Ubuntu in a VM that’s idle most of the time, so I decided to set up a jenkins user there and make use of it as a build slave in the evenings. This means that at http://ghc.newartisans.com, you’ll now find nightly builds of GHC HEAD for Ubuntu as well (64-bit). It also includes fulltest and nofib results for each build.

 Posted by at 7:32 pm
Jun 122013
 

Since mid-January, I’ve been running nightly builds of GHC on my Mac Pro for 10.8.x, 64-bit. I’ve decided to make these results publically downloadable here: http://ghc.newartisans.com.

The installer tarballs are in dist, while the fulltest and nofib logs are in logs. According to Jenkins this build takes 8h15m minutes, so I figured this might save others some CPU heat.

 Posted by at 4:35 pm
May 122013
 

Problem 1: The source of exceptions is obscured

main = getArgs >>= readFile . head >>= print . length

Even though length is a pure function, this is where the I/O will happen (lazily), which means that is where any exceptions relating to I/O will get raised. Pure code should avoid raising exceptions, which this example violates.

Problem 2: Sharing may cause file contents to remain in memory

main = getArgs >>= readFile . head >>= print . (length . words &&& length)

Because of the way that lazy I/O reads in strings, this line of code will cause the entire contents of the file to be loaded into memory by the call to either length or words, and then it will stay in memory to be handled by the other call to length. You would expect it to process the input at the very least one line at a time, to avoid exhausting memory on very large files.

NOTE: It has been pointed out that this is not really a problem with Lazy I/O, but with laziness in general. The only real way, then, in which an iteratee-type library helps here is that it’s more typical to connect sources and sinks directly together, than to read all the data from a source at one time, and then hand it to two sinks that way. So the problem there is not solved either, it’s just less common to the idiom.

Problem 3: File handles are not closed when you might expect

main = getArgs >>= mapM_ (readFile >=> print . length)

If getArgs returns N files, Haskell will open N file handles, rather than one at a time as you might expect, meaning that running this in a very large directory may exhaust system resources.

Conclusion: Use conduit/pipes/io-streams library to avoid surprises

Lazy I/O is great for prototypical simple examples, but for serious code these problems can be hard to track down — and are eliminated by a library such as conduit.

 Posted by at 7:44 pm
May 122013
 

I think one reason I’ve been avoiding posting to my blog lately is the time commitment of writing something of decent length. To get over this hump, I’m going to shift my focus to writing smaller little discoveries of things I find during my researches into Haskell and technology. Let’s see how that goes.

 Posted by at 7:43 pm