Forum Discussion

Patrick2788's avatar
Patrick2788
Silver Contributor
Oct 29, 2025

The Diagonal Suite: Gentle thunking goes a long way!

I've become a big advocate for gentle thunking - using thunks to delay eager evaluation wherever possible in generalized Lambda development. The timings are quicker and the logic is cleaner.

On the other hand, thunking the results of MAP, BYROW, or BYCOL - especially when it leads to rows of thunks - tends to introduce recombination overhead and complexity.

I think thunking is often dismissed as “too complex,” and that’s understandable if someone’s first exposure involves unwrapping a row of thunks. When used gently thunking becomes indispensable. Typically, I introduce the thunks after the initial benchmarking to see the difference in the calculation times and the after is always quicker.

To illustrate, I’ll share The Diagonal Suite - a collection of functions where thunking is used at every opportunity.  Simple, clean, deferred logic.

What are your thoughts on gentle thunking? Where have you found it helpful/harmful in your own Lambda development?

 

 

//The Diagonal Suite -  Version 1.0 -   10/27/2025
//Author:               Patrick H.
//Description:          Directional traversal and diagonal logic for 2D arrays.

// Functions:
// • Traverseλ    -     Directional traversal engine
// • ByDiagλ      -     Diagonal-based aggregation
// • DiagMapλ     -     Wrapper for diagonal matrix extraction
// • DiagIndexλ   -     Targeted diagonal extraction
// • Staircaseλ   -     Construct diagonal staircases from a vector or 2D array
//────────────────────────────────────────────────────────────


//-------------------------------------------------------------------------------------------
//Traverseλ -   Directional Axis Remapper
//-------------------------------------------------------------------------------------------

//The selected axis is remapped to the top-left traversal order.

//Accepted directions:
//  "NE" or 1 → Northeast (↗)
//  "SE" or 2 → Southeast (↘)
//  "SW" or 3 → Southwest (↙)

//Parameters:
//array     →   2D input array (scalars not accepted)
//new_axis  →   Axis direction ("NE", "SE", "SW" or 1–3)

Traverseλ =
LAMBDA(
    array,
    new_axis,

//Input validation
IF(OR(ROWS(array)=1,COLUMNS(array)=1),                "#2D-ARRAY!",
IF(AND(ISNUMBER(new_axis),OR(new_axis<=0,new_axis>3)),"#AXIS!",

LET(
    //Dimensions
    i,      ROWS(array),
    j,      COLUMNS(array),

    //Axis traversal indices (deferred)
   
    x_NE,   LAMBDA(SEQUENCE(j,,1,0)*SEQUENCE(,i)),
    y_NE,   LAMBDA(SEQUENCE(j,,j,-1)*SEQUENCE(,i,1,0)),

    x_SE,   LAMBDA(SEQUENCE(i,,i,-1)*SEQUENCE(,j,1,0)),
    y_SE,   LAMBDA(SEQUENCE(i,,j,0)+SEQUENCE(,j,0,-1)),
    

    x_SW,   LAMBDA(SEQUENCE(j,,i,0)+SEQUENCE(,i,0,-1)),
    y_SW,   LAMBDA(SEQUENCE(j,,1)*SEQUENCE(,i,1,0)),

    //Axis mode selection
    mode,   IF(ISNUMBER(new_axis),new_axis,
                              SWITCH(new_axis,"NE",1,"SE",2,"SW",3,1)),
    //Index selection
    x,      CHOOSE(mode,x_NE,x_SE,x_SW),
    y,      CHOOSE(mode,y_NE,y_SE,y_SW),
    
    //Unwrap indices and get results
    result, INDEX(array,x(),y()),
    result
)
)));

//-------------------------------------------------------------------------------------------
//ByDiagλ - Diagonal-based aggregation
//-------------------------------------------------------------------------------------------

//Apply an ETA function or Lambda to diagonals

//Parameters:
//array             →   2D input array (scalars not accepted)
//[function]        →   ETA function or Lambda applied to diagonals
//[row_wise_stack?] →   Optional: Display results as a vertical stack

ByDiagλ = 
LAMBDA(
    array,
    [function],
    [row_wise_stack?],

//Check array input
ValidateDiagλ(array,,function,row_wise_stack?,
LET(
    //Optional parameters
    No_Function,   ISOMITTED(function),    No_row_wise_stack,ISOMITTED(row_wise_stack?),

    //Dimensions
    i,      ROWS(array),
    j,      COLUMNS(array),

    //Diagonal count
    k,      MIN(i,j),

    //Indices - deferred
    r,      LAMBDA(SEQUENCE(k)*SEQUENCE(,j,1,0)),
    y,      LAMBDA(SEQUENCE(k)+SEQUENCE(,j,0,1)),
    c,      LAMBDA(IF(y()>j,NA(),y())),

    //Unwrap indices, shape, and aggregate
    result, IFNA(INDEX(array,r(),c()),""),
    shaped, IF(No_row_wise_stack,result,TRANSPOSE(result)),
    final,  IF(No_Function,shaped,
            IF(No_row_wise_stack,BYCOL(shaped,function),
                           BYROW(shaped,function))),
    final
)));

//-------------------------------------------------------------------------------------------
//DiagMapλ - Wrapper (Calls ByDiagλ) to extract diagonals as 2D matrix
//-------------------------------------------------------------------------------------------

//Calls ByDiagλ to extract the diagonals from a 2D array.

//Parameters: *Please see ByDiagλ for descriptions.**

DiagMapλ =
LAMBDA(
    array,
    [row_wise_stack?],
    ByDiagλ(array,,row_wise_stack?)
);

//-------------------------------------------------------------------------------------------
//DiagIndexλ - Targeted diagonal extraction
//-------------------------------------------------------------------------------------------

//Extract a diagonal or anti-diagonal vector from a 2D array.

//Parameters:
//array     →   2D input array (scalars not accepted)
//col_index →   Column number to start from. Negative = anti-diagonal

DiagIndexλ = 
LAMBDA(
    array,
    col_index,

//Input checks
ValidateDiagλ(array,col_index,,,
LET(
    //Dimensions
    i,      ROWS(array),
    j,      COLUMNS(array),
    
    //Diagonal direction: +1 = SE, –1 = SW
    s,      SIGN(col_index),

    //Determine diagonal length based on bounds
    k,      IF(s>0,
                    MIN(i, j + 1 - col_index),
                    MIN(i, ABS(col_index))),

    start,  IF(s<0,ABS(col_index),col_index),

    //Indices - deferred
    x,      LAMBDA(SEQUENCE(k)),
    y,      LAMBDA(SEQUENCE(k,,start,s)),

    //Unwrap indices and extract vector
    deliver, INDEX(array,x(),y()),

    deliver
)));

//-------------------------------------------------------------------------------------------
//Staircaseλ — Construct diagonal staircases from a vector or 2D array
//-------------------------------------------------------------------------------------------

//Parameters:
//array             → Input array (flattened to vector row-wise)
//block_size        → Number of rows/columns per staircase block
//[block_offset]    → Optional padding between staircases
//[IsHorizontal?]   → Optional toggle for column-wise orientation
//[IsAntiDiag?]     → Optional toggle to display staircase anti-diagonal.

Staircaseλ = 
LAMBDA(
    array,
    block_size,
    [block_offset],
    [IsHorizontal?],
    [IsAntiDiag?],

//Check inputs
ValidateStaircaseλ(array,block_size,block_offset,

LET(
    //Check optional parameters
    no_Block_Offset,    ISOMITTED(block_offset),
    zero_Offset,        block_offset=0,
    col_offset,         IF(No_Block_Offset,0,block_offset),
    IsVertical?,        ISOMITTED(IsHorizontal?),
    Not_Anti_Diag,      ISOMITTED(IsAntiDiag?),

    //Convert to vector and get dimensions
    flat,               TOCOL(array),
    k,                  COUNTA(flat),
    seq,                LAMBDA(SEQUENCE(k)),
    V,                  TOROW(EXPAND(WRAPROWS(seq(),block_size),,
                                     block_size+block_offset,0)),
    width,              COLUMNS(V),

    //Anchors and indices - deferred
    i,                  LAMBDA(SEQUENCE(block_size)*SEQUENCE(,width,1,0)),
    col_arr,            LAMBDA(IF(Not_Anti_Diag,SEQUENCE(,width),
                                                SEQUENCE(,width,width,-1))),

    j,                  LAMBDA(MOD(col_arr(),block_size+block_offset)),

    j_,                 LAMBDA(IF((no_Block_Offset)+(zero_Offset),
                               IF(j()=0,block_size,j()),j())),
    idx,                LAMBDA(IF(i()=j_(),V,NA())),

    //Obtain results, shape, and calculate
    result,             DROP(IFNA(INDEX(flat,idx()),""),,-col_offset),
    final,              IF(IsVertical?,TRANSPOSE(result),result),
    final
)));

//---------------------Error Handling & Validation---------------------------

//Validates inputs for Staircaseλ. Please see Staircaseλ for parameter
//descriptions.

ValidateStaircaseλ =
LAMBDA(
    array,
    block_size,
    [block_offset],
    [on_valid],
LET(
    //Checks
    NotArray,TYPE(array)<>64,
    Invalid_block_size,     OR(ISTEXT(block_size),block_size<=0,block_size>COUNTA(array)),
    Invalid_block_offset,   OR(ISTEXT(block_offset),block_offset<0),
    
    //Logic gate
    IF(NotArray,            "#NOT-ARRAY!",
    IF(Invalid_block_size,  "#BLOCK-SIZE!",
    IF(Invalid_block_offset,"#BLOCK-OFFSET",
    on_valid))))

);


//---------------------Error Handling & Validation---------------------------

//Validate inputs for ByDiagλ, DiagMapλ, and DiagIndexλ.
//*Please see those functions for parameter descriptions.*

ValidateDiagλ=
LAMBDA(
    array,
    [col_index],
    [function],
    [row_wise_stack?],
    [on_valid],
LET(
    //---Checks---

    //Array input
    IsArray?,               TYPE(array)=64,
    Not_Array,              NOT(IsArray?),

    //Col_index
    No_Col_Index,           ISOMITTED(col_index),
    Col_Index_Included,     NOT(No_Col_Index),
    Not_Valid_Col_Index?,   NOT(AND(col_index<>0,
                            ABS(col_index)<=COLUMNS(array))),
    
    //Function
    No_Function,            ISOMITTED(function),
    Function_Included,      NOT(No_Function),
    Invalid_Function?,      AND(ISERROR(BYROW({1,1},function))),
    
    //Shaping input
    RowWiseStack?,          NOT(ISOMITTED(row_wise_stack?)),
    
    //Deterine which function is being validated
    DiagIndex,              Col_Index_Included,
    ByDiag,                 AND(No_Col_Index, Function_Included),
    DiagMap,                AND(No_Col_Index, No_Function),

    //Logic gates
    //DiagIndexλ
    a,                      IF(Not_Array,           "#NOT-ARRAY!",
                            IF(Not_Valid_Col_Index?,"#COLUMN-INDEX!",
                                                     on_valid)),
    //ByDiagλ
    b,                      IF(Not_Array,           "#NOT-ARRAY!",
                            IF(Invalid_Function?,   "#FUNCTION!",
                                                     on_valid)),
    //DiagMapλ
    c,                      IF(Not_Array,           "#NOT-ARRAY!",
                                                     on_valid),

    //Logic gate selection                      
    decide,                 IF(DiagIndex,a,
                            IF(DiagMap,c,
                            IF(ByDiag,b,
                            "#UNROUTED!"))),
    decide
));

//End of The Diagonal Suite -   Version 1.0
//Author:   Patrick H.

 

No RepliesBe the first to reply

Resources