Sunday, May 7, 2023

Mirdin Coding Tips

Tradeoffs for Pre and Post Conditions for Code Blocks

A weaker precondition or less preconditions for a code block will be more general and less restrictive.  A stronger precondition or more preconditions results in more specific or guaranteed inputs to the code block.  

A stronger postcondition or more postconditions offer better guarantees for the output of the code block, because they restrict the development of the code block with more specificity.  A weaker postcondition or fewer postconditions offer less guarantees, but provides more room to change the implementation later.  

Decision Tables and the Code Smell due to Boolean Blindness

Decision tables or Parnas tables is clear in table form, but their T and F outputs are not descriptive and results in boolean blindness:

|n%3|n%5|   f(n)  |
|---|---|---------|
| T | T | "Both"  |
| T | F | "Three" |
| F | T | "Five"  |
| F | F | "Nil"   |

To remove boolean blindness in Haskell, we introduce pattern matching with types:

data ThreeFive = Both | Three | Five | Neither
f :: Int -> ThreeFive 
f n | n%3 && n%5 = Both
    | n%3 = Three
    | n%5 = Five
    | otherwise = Neither

Code Smells due to Linguistic Antipatterns
from https://www.linguistic-antipatterns.com/
- multiple methods with similar names or effects which are confusing
- fields or functions with names that do not match their specificity or generality
- functions with names strongly and wrongly associated with inapplicable specifications or properties
- functions with names suggesting a return type but there's no return value
- names of functions, parameters or fields do not match their types
- functions with names suggesting purity, but they actually have side effects

Quality through Representability and Validness

Representability in code is obtained by including only the necessary information and not represent things that don't exist in reality.  Validness in code is achieved when different real world situations are clearly distinguishable in the code.  The goal is SPOT or Single Point of Truth, where the data structure or system that is created has a one to one relationship with the real-world system, and quality is built into the code from the start instead of trying to test it in later.  Testing quality in later means that quality is treated as an afterthought, and efforts to improve or fix the data structure or system are made after it has already been built.  

Exhibit "Good Taste" when Coding

The crux of the “good taste” requirement is the elimination of edge cases, which tend to reveal themselves as conditional statements.  The fewer conditions we test for, the better our code “tastes”.  

Example to loop over every point in the grid and used conditionals to test for the edges:

for (r = 0; r < GRID_SIZE; ++r) {
    for (c = 0; c < GRID_SIZE; ++c) {        
    // Top Edge
        if (r == 0)
            grid[r][c] = 0;        
    // Left Edge
        if (c == 0)
            grid[r][c] = 0;        
// Right Edge
        if (c == GRID_SIZE - 1)
            grid[r][c] = 0;        
// Bottom Edge
        if (r == GRID_SIZE - 1)
            grid[r][c] = 0;
    }
}

Better version of the code with "good taste":

for (i = 0; i < GRID_SIZE; ++i) {    
    // Top Edge
    grid[0][i] = 0;
    // Bottom Edge
    grid[GRID_SIZE - 1][i] = 0;    
// Left Edge
    grid[i][0] = 0;    
// Right Edge
    grid[i][GRID_SIZE - 1] = 0;
}

Tradeoffs for DRY or Modularisation vs Coupling

DRY or Don't Repeat Yourself or modularisation reduces code bloat, but this may result in more coupled code, especially if there are cross dependencies between modules.  When the software design is apparent or clearly represented in the code, and its structure subsetted hierarchically, there will be less coupled code.  It is often not possible or practical to completely remove coupling from code, because some level of coupling and necessary dependencies are necessary for different parts of a software system to communicate and interact with each other.  The goal is to minimise and manage this coupling to create a more maintainable and flexible codebase.

Mirdin Coding Tips

Tradeoffs for Pre and Post Conditions for Code Blocks A weaker precondition or less preconditions for a code block will be more general and ...