Sunday, March 23, 2008

Some tools just don't like each other

brit·tle, adj.
  1. Multi-line string literals in Haskell require so-called "string gaps": one '\' character to terminate a line and another '\' to start the next line.
  2. With GHC, Haskell programs may be preprocessed with CPP, which coincidentally strips the "\ ... \" characters from the source, resulting in an illegal Haskell string literal.
  3. Mercifully, it also happens that CPP doesn't strip the characters if the first '\' character is followed by a space before the newline.
  4. But of course, a commonly used feature of emacs is to silently strip trailing whitespace at the end of lines on every save.
  5. Not that you can see the difference, given the well-known human limitations at visually distinguishing whitespace.
(Sensitive types should take this neither as a criticism of GHC nor as implicit condonement of using CPP for Haskell programs--I know it's shunned. You've gotta admit this is beautiful, though.)


Richard Cobbe said...

Oh, fun!

I encountered a problem similar to this in earlier versions of Quack. With this bug (since fixed), Quack treated the pipe character as whitespace. So, if you commented out a bunch of PLT Scheme code by putting #| ... |# around it, and if the comment opener was the last thing on its line, Quack and Emacs would delete the pipe, and your comment was suddenly a syntax error!

I got around this by adapting the line eater food strategy and putting some random stuff after the pipe so that it was no longer trailing whitespace. If GHC allows non-whitespace chars between the backslashes, you can do something similar. It's an annoying, crufty workaround, but it gets you past the original problem.

Paul Steckler said...

I've gotten bitten by this stuff when trying to compile Haskell libraries with multi-line string literals (I can't imagine writing such a thing myself).

My solution, IIRC, was to turn the strings into lists of strings that were concat'd.

Despite its deprecation, I've seen lots of Haskell code that uses cpp, mostly for conditional compilation.

-- Paul

Anonymous said...

I blame your text editor. *hem*


Anonymous said...

Yeah, use cpphs. Actually, I think it's quite idiomatic to use ++, unwords, unlines, etc.

Mike Machenry said...

Watch out. You're just begging for an emacs/vi flame war. Any little thing will set them off :)

Great post though. Hope you're doing well.