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:
What functional decomposition is
How functional decomposition helps create and debug code
How the LET() function makes functional decomposition easy
Prerequisites
Understanding of the LET() function
Classes
Introduction to Component Based Software Engineering
Introduction to LAMBDA Source Structure
Making LAMBDAs "Self-Contained"
Documenting LAMBDAs
Commenting LAMBDA Source
Providing Inline Documentation
Validating Function Arguments
Using LET() to Improve Readability and thus, Maintainability
Testing Components
Certifying Components
Distributing Components and Version Control
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.