5G Functional Decomposition

Description
Though not a requirement, a good coding practice is known as Functional Decomposition

Learning Objectives
At the end of this course, learners will know:

Prerequisites
Understanding of the LET() function

Classes

Discussion

Functional decomposition is the process of splitting larger, complex problems into smaller, simpler problems. Simpler problems are easier to understand and debug. To illustrate we will use the following example.

MAKEARRAY(ROWS(Date1), COLUMNS(Date1),
    LAMBDA(R, C,
        Switch(Interval,  
            "D", SIGN(Max(INDEX(Date2, R, C) - INDEX(Date1, R, C), 1)) *
                DATEDIF(MIN(INDEX(Date1, R, C), INDEX(Date2, R, C)),
                        MAX(INDEX(Date1, R, C), INDEX(Date2, R, C)) + 1, "D"),
            "W", SIGN(Max(INDEX(Date2, R, C) - INDEX(Date1, R, C), 1)) *
                DATEDIF(MIN(INDEX(Date1, R, C), INDEX(Date2, R, C)),
                        MAX(INDEX(Date1, R, C), INDEX(Date2, R, C)) + 1, "D")/DPW,
            "M", SIGN(Max(INDEX(Date2, R, C) - INDEX(Date1, R, C), 1)) *
                DATEDIF(MIN(INDEX(Date1, R, C), INDEX(Date2, R, C)),
                        MAX(INDEX(Date1, R, C), INDEX(Date2, R, C)) + 1, "M"),
            "Q", SIGN(Max(INDEX(Date2, R, C) - INDEX(Date1, R, C), 1)) *
                DATEDIF(MIN(INDEX(Date1, R, C), INDEX(Date2, R, C)),
                        MAX(INDEX(Date1, R, C), INDEX(Date2, R, C)) + 1, "M")/MPQ,
            "Y", SIGN(Max(INDEX(Date2, R, C) - INDEX(Date1, R, C), 1)) *
                DATEDIF(MIN(INDEX(Date1, R, C), INDEX(Date2, R, C)),
                        MAX(INDEX(Date1, R, C), INDEX(Date2, R, C)) + 1, "Y")

        )
    )
)

The long formulas are a bit difficult to read. More importantly, trying to debug this as a LAMBDA is not as easy as it could be. This is especially true because it appears likely that some of the code repeats but without careful inspection, we cannot be sure. Now consider the same routine code this way:

LET(Rows,   ROWS(Date1),
    Cols,   COLUMNS(Date1),
    Result, MAKEARRAY(Rows, Cols,

                LAMBDA(R, C,

                    LET(DateOne,    INDEX(Date1, R, C),

                        DateTwo,    INDEX(Date2, R, C),        

                        Earliest,   MIN(DateOne, DateTwo),

                        Latest,     MAX(DateOne, DateTwo) + 1,

                        Sign,       SIGN(Max(DateTwo - DateOne, 1)),

                        Periods,    Switch(Interval,  

                                        "D", DATEDIF(Earliest, Latest, "D"),

                                        "W", DATEDIF(Earliest, Latest, "D")/DPW,

                                        "M", DATEDIF(Earliest, Latest, "M"),

                                        "Q", DATEDIF(Earliest, Latest, "M")/MPQ,

                                        "Y", DATEDIF(Earliest, Latest, "Y")

                                    ),

                        Sign * Periods

                    )

                )

            ),

The code is much easier to understand because we can see things like MIN(DateOne, DateTwo)is determining which date is the Earliest date. 

We can also know that the repeating code, such as INDEX(Date1, R, C) is indeed identical now that it doesn't repeat. 

Functional decomposition also makes debugging much easier as we can replace the last line of the LAMBDA with one of the LET() function's names. So if we want to know how the sign is being calculated, we can return Sign instead of Sign * Periods.

Lab
Without looking at the bottom code, try your hand at decomposing the top code.

Summary

The functional decomposition technique can make our code easier to understand and debug.

Assessment

Coming soon.