[Haskell-cafe] Line noise

wren ng thornton wren at freegeek.org
Sun Sep 21 22:49:19 EDT 2008

Andrew Coppin wrote:
> I hang out on another forum that is populated by various kinds of 
> computer geeks. There's a fair few programmers in there, as well as 
> nerds of every degree. And yet, every time I post anything written in 
> Haskell, everybody complains that it "looks like line noise".
> Actually, none of these things were mentioned. The things people have 
> *actually* complained to me about are:
> - Haskell expressions are difficult to parse.

To anyone who doesn't know the language, this seems quite true. Haskell 
was designed with a hyper-minimalist syntax, whereas C/C++/Java are very 
heavy with syntactic boilerplate. I am a devout fan of the minimalism, 
but it is something of a barrier to entry for those unwilling to 
consider anything that doesn't look familiar.

We inherited our use of spaces for function application from Lisp and 
friends, so "foo bar baz" looks perfectly natural to functionalists. But 
to those used to seeing "foo(bar, baz)" the meaning attached to the 
spaces is alien. The 'difference' in meaning for the two spaces only 
drives the alienness home, since (ubiquitous) currying is not well known 
or practiced outside of Haskell. Even with functionalists ---of the 
OCaml and SML ilk--- this use of spaces can be confusing if noone 
explains that function application binds tighter than all operators.

Similarly, we use linebreaks to denote various things whereas the 
syntax-heavy languages require a semicolon or similar delimiter. We are 
in fortuitous arms here since we can use the redundant {;} notation to 
sell new folks. Though it is wise to use the notation with the semicolon 
trailing on the previous line:

     do {

rather than the more idiomatic leading version:

     do { foo
        ; bar
        ; baz

Again, the minimalist version that omits the {;} which lends a meaning 
to whitespace that syntax-heavy users are not familiar with. Here I 
think is largely a question of knowing your audience; the explicit 
version is better for any audience with many non-Haskell folks, even if 
it's a functional audience.

We also allow for omitting parentheses in many places required by other 
languages. In particular, the case...of construct mentioned previously. 
The if...then...else construct can have similar problems, though they 
are more easily overlooked by foreigners. Again this is easy to correct 
for when talking with outsiders: just add redundant parentheses.

The meaning of = and how it differs from -> are also quite subtle. 
Pattern matching and guards, like currying, are concepts that are quite 
alien to users of most other languages. The simplicity of their syntax 
in Haskell probably serves to further confuse questions of the syntax 
associated with =. I know from experience that these simple ideas can be 
a tough sale. Few languages have the notion that defining a function is 
the same as any other 'assignment' and so most languages have radically 
different syntaxes for the two. This trait of treating functions as 
first-class citizens tends to have large brain-breaking capabilities-- 
moreso than passing functions as arguments, it seems.

All of these are just basic things about Haskell's syntax and have 
nothing to do with all the interesting higher-order stuff which is 
really novel. It is unfortunate that there are so many people, 
intelligent people even, who are so hidebound as to be unwilling to 
gloss over syntax, but sadly it is the way of things. To be fair to 
them, the meanings assigned to whitespaces are not the sort of thing 
which is trivial to intuit. Perhaps we need a _Guide to Reading Haskell 
(for non-Haskell Programmers)_?

Live well,

More information about the Haskell-Cafe mailing list