BlockArgument and $

Fair enough, event though personnaly find the arguments a bit weak. But as far as I understand, the harm has been done, so adding more whitespace would not change anything, wouldn’t it ?

(I suggest you look at my vim word-indent
plugin especially the shift section shift example.

It actuallys changed my (indenting) life
)

1 Like

With vim, the mark ] is set on the last yanked character. So when you move stuff arround, after you pressed p, to indent you just need to press >'] (or <']) and repeat (.). If it’s too long and you need it lots you could do some mappings.

3 Likes

I consider myself one of the more disciplined programmers out there as far as coding style goes, but even so I don’t want to depend on discipline to keep my programming tools reliable. The whole point of those tools is to automate things for me so that I don’t have to waste brain resources on silly stuff like spotting incorrect indentation. And the code I have to work with is, more often than not, not mine in the first place, and I have zero leverage for disciplining others.

I’m also a huge fan of deterministic, predictable tools - part of what I love about vim is that I can keep typing commands without waiting for the editor to execute them; but if I have to double-check the result of each command, the “pipeline” breaks, and I have to downshift to a cycle of “issue a command, look at the result, decide whether the command did what I wanted, issue next command, repeat”. It also makes vim’s macros (the q/@ commands) less useful.

But that’s the thing - can the formatter even fix it? In the JS example, it would turn it into:

return;
getRavenousness(bugblatterBeastOfTraal) > 1;

…which actually makes it easier to spot the problem, but that’s only possible because JS doesn’t do full significant whitespace (and especially, indendation doesn’t matter in JS, only newlines).
In the Haskell example, the formatter might not even help; the code is invalid no matter how you change the indentation, and while running it through a formatter will probably give you a different error, that won’t necessarily tell you what the actual problem is. And because the code is malformed either way, it could end up guessing your intention wrong, adding confusion rather than removing it. Consider the options a formatter has:

main = do
    let greet name = do
    putStrLn $ "Hello, " ++ name ++ "!"

That fixes the outer do block, but produces an empty inner do block, and an undefined variable name (but the formatter probably doesn’t do an actual compilation pass to figure this out, so it can’t tell).

main = do
    let greet name = do
            putStrLn $ "Hello, " ++ name ++ "!"

Now your outer do block is empty, but the inner one is fixed. This is probably what you wanted, but how is the formatter to know?

Now let’s look at the same example with explicit braces:

main = do {
    let greet name = do {
        putStrLn $ "Hello, " ++ name ++ "!"
    }
}

No ambiguity, and the formatter can just go ahead and indent the thing exactly as you meant it, regardless of those empty do blocks. You can even mangle it into:

main=do{let greet name=do{putStrLn$"Hello, "++name++"!"}}

…and it’s still unambiguous.

You can, but:

  • The code will still be unambiguous, usually even when it’s malformed, so running it through a formatter will actually help.
  • The block delimiter tokens can always be distinguished visually, so your odds of staring down the problem are greatly increased. This holds doubly in the presence of inconsistent line breaks, tabs, etc.

Touché - here, another little wart shows up, which is that we need an explicit return () to indicate a do-nothing do block (which is eerily similar to Python’s pass). Personally, I’d prefer empty do blocks to implicitly mean return (), but unfortunately that’s not the case (and also if they did, it would break layout in much the same way as not having pass would break Python’s indentation-based blocks).

I’m with you on the Reddit thing, but that’s not the point, I was just using Reddit as an example. The same holds true, to varying degrees, for all platforms out there, even this one here. As long as you use the formatting syntax correctly, your indentation will usually be preserved, but there’s just too many subtly different formatting syntaxes out there, and most users have simply given up on mastering them all. I use about a dozen different platforms on a regular basis, and they all use some kind of markdown, but no two of them use the same flavor. I still have to consult the documentation for each of them all the time in order to use them correctly.

The initial message is not usually a problem, but when a whole conversation goes back and forth through a mailing list, and some people on that list reply in HTML, and then the rest of the users use various HTML-to-text converters to get things back into sanity, and then email clients and mailing list software and other things along the path add line breaks and quotation markers and whatnot, then things can get pretty awful.

2 Likes

The harm is currently limited due to the fact that layout sections in Haskell tend to be small (and when they’re not, splitting them up into smaller chunks is probably a good idea anyway); that’s still a million times more tolerable than having layout everywhere.

Formatter can format things given enough hints (usually one or two tabs) which is usually less than two brackets. I personnaly don’t use formatter and just indent along.

So if you saying that layout is bad because forgetting tabs is ambiguous i can say the same about braces . If you forget or can’t be bothered to type braces then is ambiguous too.

That’s not what I’m saying at all.

Indentation-based syntax is ambiguous when there are programming errors, yes, and so are brackets; but:

  • Indentation-based syntax is also often ambiguous when there are no programming errors
  • Programming errors, when they do occur, are harder to spot, and tend to cause more confusing error messages
  • Editor ergonomics tend to be significantly worse

Let’s have another look at the quotes which seems to have started this subthread about layout sensitivity:

  • …that remark was about this particular lexing rule:

    In all the Haskell front sections I can vaguely recall seeing, that rule (and the associated note) did result in “intriguing” code. But according to this site at least:

    TIOBE Index - TIOBE

    …right now, another layout-sensitive language is the most prevalent - that’s one heck of a coincidence (if it is one).

  • …and “ease of implementation” cannot always take priority over “ease of use” - a balance needs to be found. And as techniques and tools are discovered and improved, that balance will invariably shift as a result.

Now for those who don’t like layout sensitivity (in Haskell anyway), here’s something to consider:

  • If Haskell did have a syntax more like C, how long would it have remained as a non-strict language, particularly after the official arrival of the monadic interface in version 1.3 ?

    (…if you’re not sure, have a look at the amusing confusion caused by

    return :: Monad m => a -> m a

    since version 1.3 - it’s fortunate that there’s no function called while in the Haskell standard: it probably would be appearing frequently at the end of do loops blocks ;-)