Internal assignment

Internal assignments can make code hard to read, especially if there’s a lot of it. For example, in the following line

i:where(k>v@y)&(k:til s)<first(1+y)_ v,s:count n

there are internal assignments of k and s.

Internal assignments should never span lines. That is, the value should be read only on the line on which it is set. In the example above, k and s should be temporary assignments on the way to computing i. If q had a with clause, we would write this differently:

i:where(k>v@y)&k<first(1+y)_ v,s with k:til s with s:count n

The aim of this line is to construct i. Rather than compute count n three times, and til count n twice, we snarf these values into temporaries the first time they are computed.

If k and s are to be read on subsequent lines, they should be assigned in their own statements:

s:count n;
k:til s;
i:where(k>v@y)&k<first(1+y)_ v,s;
…

Now the reader can scan the left edge of the function text and find all non-temporary assignments.

Test your code by mentally drawing arrows from each assignment to each use of the name assigned.

  • Arrows should never go up or to the right: that means you’re re-using a name.
  • Arrows going down should always originate at the left edge of a line.
  • Arrows going left are temporaries, and should never also go down.

It’s a good idea to pick one or two letters for the purpose of temporary assignment, and use them constantly and exclusively for this purpose. (t and u are good. And if you do so, then modify the arrow test above to allow for re-use of those names on successive lines.)

Three Principles of Coding Clarity: The first principle: shorten lines of communication