The great evil of co-linear closure declarations

I am personally opposed to this:

try fopen(moduleMapPath, mode: .Write) { fp in
    try fputs("\n", fp) 
}

Why put the declaration line in a complete different place from the rest of the code? Move it down and let it annotate the use that follows:

try fopen(moduleMapPath, mode: .Write) { 
    fp in
    try fputs("\n", fp) 
}

Today’s complaint is brought to you by the letters “i” and “n” and the return type Void.

4 Comments

  • Agreed. Thank you for saying what I was thinking.

  • first one is much cleaner

    • How so? The difference is entirely whitespace, but in the first, statements within the inner scope share the line with those evaluated in the outer scope. Truth be told, I’d prefer a usage where fp could be bound for the inner scope before entering the scope (akin to “with” in python) – but given a multiline closure, block delimiter treatment should be consistent with other cases.

      (That said, I’d happily accept an argument for replacing the closure here with a single line ‘{ try fputs(“\n”, $0) }’)

      • It’s a matter of tracking where the eye (and brain) have to scan. Leaving aside anonymous arguments as a shortcut, the closure declarations, when used, establish parameter names and return types that should be as close to in-line as possible. This allows the reader to scan from top to bottom.

        I’m also forcing myself to use the newline dot pattern for long chaining (say over 2 chains) for exactly the same reason. Top-to-bottom visual scanning, and better documentation access points