Crafting data structures is an art

Engineering is the art of not constructing; or, to define it rudely but not inaptly, it is the art of doing that well with one dollar which any bungler can do with two. [Arthur Wellington]
If code cannot be confidently understood, it will be accidently broken. [James Coplien]
Consider the following example from The Elements of Programming Style that originally appeared in a programming textbook. It converts a julian date to its corresponding month/day/year representation.

The original implementation (below) is PL/I. The spaghetti goto flow of control is a "riddle wrapped in an enigma shrouded in mystery". On the right, it has been rewritten in Java, and the logic flows from top to bottom.

Notice the clever use of the variable "leap" to account for the extra day that is introduced every fourth year. Also, notice the very repetitive logic codified in the enormous "case" statement. There ought to be a way to collapse all these "trees" into a more interesting "forest".

    DATES:  PROC OPTIONS (MAIN);
    READ:   GET DATA (IYEAR, IDATE);
            IF IDATE < 1 | IDATE > 366 | IYEAR < 0 THEN
               RETURN;
            IF IDATE <= 31 THEN GO TO JAN;
            L = 1;
            I = IYEAR/400;
            IF I = IYEAR/400 THEN GO TO LEAP;
            I = IYEAR/100;
            IF I = IYEAR/100 THEN GO TO NOLEAP;
            I = IYEAR/4;
            IF I = IYEAR/4 THEN GO TO LEAP;
    NOLEAP: L=0;
            IF IDATE > 365 THEN RETURN;
     LEAP:  IF IDATE > 181 + L THEN GO TO G181;
            IF IDATE > 90 + L THEN GO TO G90;
            IF IDATE > 59 + L THEN GO TO G59;
            MONTH = 2; IDAY = IDATE - 31; GO TO OUT;
      G59:  MONTH = 3; IDAY = IDATE - (59 + L); GO TO OUT;
      G90:  IF IDATE > 120 + L THEN GO TO G120;
            MONTH = 4; IDAY = IDATE - (90 + L); GO TO OUT;
     G120:  IF IDATE > 151 + L THEN GO TO G151;
            MONTH = 5; IDAY = IDATE - (120 + L); GO TO OUT;
     G151:  MONTH = 6; IDAY = IDATE - (151 + L); GO TO OUT;
     G181:  IF IDATE > 273 + L THEN GO TO G273;
            IF IDATE > 243 + L THEN GO TO G243;
            IF IDATE > 212 + L THEN GO TO G212;
            MONTH = 7; IDAY = IDATE - (181 + L); GO TO OUT;
     G212:  MONTH = 8; IDAY = IDATE - (212 + L); GO TO OUT;
     G243:  MONTH = 9; IDAY = IDATE - (243 + L); GO TO OUT;
     G273:  IF IDATE > 334 + L THEN GO TO G334;
            IF IDATE > 304 + L THEN GO TO G304;
            MONTH = 10; IDAY = IDATE - (273 + L); GO TO OUT;
     G304:  MONTH = 11; IDAY = IDATE - (304 + L); GO TO OUT;
     G334:  MONTH = 12; IDAY = IDATE - (334 + L); GO TO OUT;
    OUT:    PUT DATA (MONTH,IDAY,IYEAR) SKIP;
            GO TO READ;
    JAN:    MONTH=1; IDAY=IDATE; GOTO OUT;
            END DATES;
    
 
String convert_julian( int year,
                       int julian ) {
  int leap = 0, month, day;
  if (year % 400 == 0)
    leap = 1;
  else if (year % 100 == 0)
    ;
  else if (year % 4 == 0)
    leap = 1;
  if (julian <= 31) {
    month = 1;
    day = julian;
  } else if (julian <= (59+leap)) {
    month = 2;
    day = julian - 31;
  } else if (julian <= (90+leap)) {
    month = 3;
    day = julian - (59+leap);
  } else if (julian <= (120+leap)) {
    month = 4;
    day = julian - (90+leap);
  } else if (julian <= (151+leap)) {
    month = 5;
    day = julian - (120+leap);
  } else if (julian <= (181+leap)) {
    month = 6;
    day = julian - (151+leap);
  } else if (julian <= (212+leap)) {
    month = 7;
    day = julian - (181+leap);
  } else if (julian <= (243+leap)) {
    month = 8;
    day = julian - (212+leap);
  } else if (julian <= (273+leap)) {
    month = 9;
    day = julian - (243+leap);
  } else if (julian <= (304+leap)) {
    month = 10;
    day = julian - (273+leap);
  } else if (julian <= (334+leap)) {
    month = 11;
    day = julian - (304+leap);
  } else {
    month = 12;
    day = julian - (334+leap);
  }
  int yr = year - (year/100 * 100);
  return fill(month) + '/'
         + fill(day) + '/' + fill(yr);
}

The following alternative algorithm probably took a little extra time to conceive, but, may have taken less time to write and test, and definitely takes less effort to maintain. I first saw this design in The C Programming Language published in 1978.

Instead of a cumbersome "case" statement, and its inherent control logic overhead; the author has created an array data structure. The elements of the array are the number of days per month. The fidelity of the data is easy to inspect visually. An alternative could be an array of running totals (i.e. 31, 59, 90, ...), so that the "-=" operator is not required in the for loop. But this choice would not have been as easy to understand by all subsequent readers of this algorithm.

To accomodate leap year calculations, a little extra storage was used to provide a parallel instance of the days-per-month table. While this use of memory is less than optimal, the choice has enhances the program's readability. Another trade-off is the addition of a thirteenth column to the table. Humans expect months to be represented with the numbers one through twelve. Arrays in Java are indexed starting at zero. To forego the need of incrementing a variable's value so that it can be used to output the correct month, the "zeroth" column is smiply not used.

All the logic for deciding if the specified year is a leap year is captured in a single compound ternary operator. It is arguable whether this shoots the function's readability in the foot; but this kind of code is a fairly common C idiom. Once the leap year decision is made, it is represented as an integer - not a boolean. This allows the decision to be used as an index into the days-per-month table.