Our IdExtenso framework includes a tiny module called $$.ArrayAs2D, previously discussed here. Working with two-dimensional Array objects, this tool enables syntactic operator overloading (+, -, *, etc.) to simplify complex expressions such as vector addition, dot product, angle calculation, point rotation, and similar acrobatics.

The most straightforward example involves the + operator:

var A = [3, 4]; // point or vector
var B = [5, 6]; // point or vector
 
// Invalid in standard JavaScript
// but functional with $$.ArrayAs2D():
 
var R = A + B; // => [8, 10]
 

The expression A + B, which normally only applies to numbers (addition) or strings (concatenation), becomes operational in the context of two-dimensional arrays.

Formally, $$.ArrayAs2D asks ExtendScript to interpret [x1,y1] + [x2,y2] as equivalent to [x1+x2, y1+y2]. In other words, since the elements x1, x2, y1, y2 are numbers that can be added, the interpreter executes x1+x2 and y1+y2 respectively, then aggregates these results into the output array.

What's the mechanism's core principle? Make the symbolic addition of complex objects (such as A and B above) syntactically valid by defining the operation rules and providing the means to compute results through primitive operations.

Once this concept is understood, the syntactic efficiency becomes apparent. For instance, A + B is obviously more readable than [ A[0]+B[0], A[1]+B[1] ], despite being functionally equivalent.

The Recursive Twist

The interesting behavior emerges when we examine the implementation details. To enable + operator overloading, the code sets a minimal rule: “if A and B are two-element arrays, then A + B designates the two-element array resulting from [A[0]+B[0], A[1]+B[1]]”. Nothing more, nothing less.

Additional constraints on internal element types could have been implemented — validation checks for defined values, numeric types, etc. However, for performance optimization, $$.ArrayAs2D enforces only one requirement: operands must be two-element arrays. The client code bears responsibility for using this tool appropriately and invalid inputs will generate fatal errors, as you expect!

This led to an interesting thought experiment. Consider the case where A and B are two-dimensional arrays whose elements are themselves two-dimensional arrays:

// Assuming internal variables represent
// numeric x and y coordinates.
 
var A = [ [xMin_A, yMin_A], [xMax_A, yMax_A] ];
var B = [ [xMin_B, yMin_B], [xMax_B, yMax_B] ];
 

This structure possibly represents a bounding box implementation, encapsulating minimum/maximum coordinates along both axes. Geometric operations on such structures (overlap detection, inclusion testing) require computing centroids, dimensions, coordinate-wise subtraction, etc.

The critical question:
   Does A + B still make sense?

Examining the + operator signature carefully reveals that operands A and B satisfy the sole requirement we've established: each is unambiguously a two-element array. Consequently, the interpreter should process A + B as symbolically equivalent to [ A[0]+B[0], A[1]+B[1] ]. Will the interpreter reject this operation?

No. Each exposed operand is itself a two-element array (e.g., A[0] corresponds to [xMin_A, yMin_A]), allowing the interpreter to apply identical composition rules recursively.

This reveals a key insight: operator overloading functions recursively when circumstances require it, provided that at each operational stage we encounter two-element arrays containing additive elements.

Testing this theory in IdExtenso with concrete values confirms the behavior:

//         X1 Y1    X2 Y2
var A = [ [ 1, 2], [ 3, 4] ];
var B = [ [10,20], [30,40] ];
 
var R = A + B;  // [ [11,22], [33,44] ]  :-)
 
alert( R.join('\r') );
//       11,22
//       33,44
 

As predicted, the result is an array composed of two two-element arrays. In terms of code economy, the expression A + B encapsulates in three symbols what would otherwise require an unwieldy expression exceeding 70 characters — an exercise left to the reader…


See also:

$$.ArrayAs2D.jsxlib (IdExtenso module)
IdExtenso, the scripting framework for InDesign ninjas
“Let's Play with JS Array Objects”
“Operator Overloading with ExtendScript”