13
$\begingroup$

Preamble

Following the recommendation of a presentation or article which I now only vaguely remember I have been experimenting with a particular code format:

fn[args_] := (
  expr 
    // operation1
    // operation2
    // operation3
)

Each operation is cast as a Function as necessary, though operator forms are used where available. Some examples: (138146), (138650), (139228).

I have found this format to be reasonably general and have above average readability. I note that my use of it (which is by no means unique) seems to be well accepted so I think others must find it readable too.

A couple of things keep me from adopting this format as my go-to style: the first is the requirement for additional Function constructs over more heavily bracketed code. The second is the way that this code is automatically formatted in Notebook Input Cells which is what my question is about.

(Pardon the long introduction but I feel that context is necessary.)

Summary

When multiple // postfix operations are written one on each line the standard code indenter does this:

enter image description here

I find this indenting weird and inconvenient. I suppose it exists to indicate that operation1 is "inside" operation5, etc., but that's not really how I think about these operations; rather I think of them as a series of sequential steps performed in order from one to five.

It also ends up crowding code into the right margin when there would otherwise be plenty of room.

Question

All that out of the way my actual question is this: do other people regularly benefit from the indenting shown above, and what coding style(s) is it useful for?

If this indenting is not of use in other styles or from different perspectives I would perhaps campaign to have the indenting changed in future versions to the vertically aligned form shown in the first code block in this question.

$\endgroup$
16
  • 1
    $\begingroup$ @jjc385 Take for example the splitEvery code from (139228). That could instead be written as splitEvery[list_, x_, n_Integer] := MapThread[Take[list, {##}] &, {Prepend[# + 1, 1], Append[#, -1]}] &[ SparseArray[Unitize[list - x], Automatic, 1]["AdjacencyLists"][[n ;; ;; n]] ] which I find considerably less readable, however it involves fewer total operations because it eliminates several Function constructs. $\endgroup$
    – Mr.Wizard
    Mar 6, 2017 at 6:17
  • 1
    $\begingroup$ Very much opinion-based indeed. I'd remark, basing this on coding style guidelines of more traditional programming languages, that if you really run into the problem of code being pushed into the right margin, perhaps your postfixed functions are too long, complex, and maybe not so readable, which seems contrary to your intent. This reminds me of your question from some time ago about verbose vs. terse code, where you and Leonid had a rather lengthy discussion. It would be good to link it here. $\endgroup$
    – LLlAMnYP
    Mar 6, 2017 at 13:32
  • 1
    $\begingroup$ (131919) asks a similar question with respect to currying and right-composition operators. +1 for chaining operations using // and vertical alignment. I have given up fighting the parser and reluctantly put the operators on the end of the preceding line instead of the start of the next. I still fight the auto-formatter, though, by using code cells for everything but one-off evaluations. I'm not sure my opinion counts for much given my alien indentation style :) The formatter could be readily fixed but a parser change is unlikely. $\endgroup$
    – WReach
    Mar 6, 2017 at 15:44
  • 2
    $\begingroup$ The mirror image of this happens when you replace // by @ and reverse the order. So your interpretation of the indentation is likely correct. But that also means that changing it just for // may not be consistent in the bigger picture. $\endgroup$
    – Jens
    Mar 6, 2017 at 17:10
  • 1
    $\begingroup$ Related: 80184 $\endgroup$
    – Carl Woll
    Jun 5, 2019 at 16:06

1 Answer 1

7
$\begingroup$

As requested, I'll expand on my comment a little. The indentation makes sense if you look at the following comparison of four constructs, where the first one is from the original question:

You see the same indentation in the first two examples, and the opposite indentation in the remaining two. The examples built with just Lists illustrate that the indentation is determined by the nesting level. The more deeply nested, the larger the automatic number of LineIndents is. Recall that the actual interpretation of the input for fn is operation3[operation2[operation1[expr]]].

This is why the indentation decreases downward in the first two examples but increases in the last two: as the List constructs make explicit, the operations nearest to expr are deepest. The @ operator is the "counterpart" of // in that it allows you to reverse the order of operators and arguments. This reversal is what causes the reversed indentation.

In conclusion, the choice of indentation is consistent with the general prescription followed by the notebook interface, to indent according to nesting level. Changing this for // alone would then give you inconsistent indentation if you also use @ (or in fact any other nested expressions).

$\endgroup$
3
  • $\begingroup$ I never really noticed this level of internal consistency in indentation. Frankly it always seemed rather capricious and more often than not I either avoid it (one-liners) or use manual indentation. Thank you for helping me see the structure that exists. I better appreciate the choices of the designers, and hopefully in the future I will better interact with this. $\endgroup$
    – Mr.Wizard
    Mar 7, 2017 at 5:45
  • $\begingroup$ @Mr.W I never realized that your question was in fact so simple. I now think your preamble actually made the question more about a discussion of coding practices and less about the behavior of indentation (which you self-answered in the body of the Q anyway). I certainly take my words back, this isn't opinion based and is very answerable. +1, especially for the examples with lists. $\endgroup$
    – LLlAMnYP
    Mar 7, 2017 at 7:08
  • $\begingroup$ @LLlAMnYP Sorry for writing the question so poorly. I could tell is wasn't coming out well but somehow I couldn't see what the problem was. $\endgroup$
    – Mr.Wizard
    Mar 7, 2017 at 7:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.