[Haskell-cafe] Indentation woes
Tillmann Rendel
rendel at rbg.informatik.tu-darmstadt.de
Thu Jul 26 22:02:20 EDT 2007
Stefan O'Rear wrote:
> Out of curiousity, what do you find objectionable about (legal):
>
> function argument argument2
> | guard = body
> | guard = body
>
> as compared to (currently illegal):
>
> function argument argument2
> | guard = body
> | guard = body
I see the vertical strokes as visually lining up, pointing at something.
In the legal example, they are pointing to the second character of the
function name, wich has no meaning, but in the currently illegal
example, they are pointing to the function name as a whole, wich has a
meaning: To see wich function we are defining here, follow the vertical
strokes upwards. (I don't need the strokes to show me that, of course, I
just don't want them to distract me by pointing at a random position).
As I understand it, the idea behind layout is to use indention to
express tree-like structures in plain text:
root
first level node
second level node
another second level node
another first level node
second level node in a different subtree
This is fine as long as no vertical strokes show up at the beginning of
lines, since vertical strokes are sometimes used to express
tree-like structures in plain text, too:
root
| first level
| | second level
| | another second level node
| another first level node
| | second level node in a different subtree
The plain text parser embedded into my eyes seems to expect something
like the latter tree encoding when it sees vertical strokes at the
beginning of lines, but Haskell layout works more like the former.
To help my eyes, I try to write the whole pattern in a single line.
function argument argument2 | guard1 = body1
| guard2 = body2
If lines get too long this way, I wrap the body, not the pattern:
function argument argument2 | guard1 =
body1
function argument argument2 | guard2 =
body2
Of course, if I want to have local definitions visible to both bodies, I
have to write something like this:
function argument argument2 = result where
result | guard1 = body1
result | guard2 = body2
helper = ...
other_stuff = ...
I don't think this is a layout problem, I think this is a pattern syntax
problem. (Or it may be a problem of my eyes). As I understand it, the
layout rule is not made for stuff starting with keywords, but for stuff
starting with identifiers, to avoid having to use keywords. But "|" is
clearly a keyword here. So if I were to design it, I would try to get
rid of the repeated "|" keyword, maybe allowing the running example to
be written as
function argument argument2 |
guard1 = body1
guard2 = body2
wich seems to be much clearer for my eyes. Another option would be
function argument argument2 = guard1 -> body1
| guard2 -> body2
wich is good because "|" now works like in data defintions, meaning
"alternatively", but bad because the "pattern matching stops when
crossing the equals sign"-rule no longer holds.
Tillmann
More information about the Haskell-Cafe
mailing list