Révélations (inouïes) sur les opérateurs « méta-surchargés »
February 17, 2026 | Tips | fr | en
C'est en travaillant sur l'implémentation d'un système de bounding boxes que j'ai découvert presque par accident une propriété à la fois inattendue et vertigineuse de la surcharge d'opérateurs dans ExtendScript. Attention, le billet est dense mais vos neurones vont voir du pays...
Le framework IdExtenso propose un petit module $$.ArrayAs2D déjà mentionné par ici. Prenant pour contexte les objets de type tableau (Array) à deux dimensions, ce module active un mécanisme de surcharge syntaxique des opérateurs (+, -, *, etc.) de façon à simplifier l'écriture d'expressions complexes telles que l'addition de vecteurs, le calcul d'un produit scalaire, la recherche d'angles, la rotation d'un point autour d'un autre, et ainsi de suite.
L'exemple le plus trivial est celui de l'opérateur +. Il parlera mieux qu'un long discours :
var A = [3, 4]; // point ou vecteur var B = [5, 6]; // point ou vecteur // Ne fonctionne pas en JavaScript standard // mais fonctionne avec $$.ArrayAs2D() : var R = A + B; // => [8, 10]
L'écriture A + B, qui normalement n'a de sens qu'appliquée à des nombres (addition) ou à des chaînes de caractères (concaténation), devient ici opérationnelle dans le contexte des tableaux à deux dimensions.
Formellement, $$.ArrayAs2D enjoint ExtendScript d'interpréter [x1,y1] + [x2,y2] comme tenant lieu de [x1+x2, y1+y2]. Dans la mesure où les éléments x1, x2, y1, y2 désignent des nombres parfaitement qualifiés pour s'additionner, l'interpréteur ne voit aucun problème à calculer respectivement x1+x2 et y1+y2, puis à regrouper ces deux termes dans le tableau résultant.
Toute la magie de l'affaire repose sur l'idée de rendre grammaticalement correcte l'addition symbolique d'objets complexes, tels que A et B dans le code ci-dessus, sous réserve de fournir la loi et les moyens de produire un résultat par des calculs plus primitifs.
Une fois cette idée bien digérée, on mesure très vite l'économie d'écriture qui en résulte. Par exemple, A + B est infiniment plus confortable que [ A[0]+B[0], A[1]+B[1] ], expression réellement exécutée dans l'arrière-cuisine.
Le virage récursif
Okay, c'est maintenant que le vent va souffler ! Pour instituer la surcharge de l'opérateur, le module se contente de poser une règle tout à fait minimale qu'on pourrait paraphraser ainsi : « si A et B sont des tableaux à 2 éléments, alors la syntaxe A + B exprimera le tableau à deux éléments résultant de [ A[0]+B[0], A[1]+B[1] ] ». Ni plus, ni moins.
Techniquement on aurait pu ajouter diverses contraintes sur la nature des arguments internes, s'assurer qu'ils soient définis, possèdent un type numérique, etc. Mais, pour des raisons de performance, $$.ArrayAs2D s'assure d'une seule chose, l'accessibilité de l'opérateur à n'importe quel tableau à deux éléments. Après tout, c'est au code client d'utiliser cet outil dans les conditions appropriées. Si vous lui envoyez du jus de tomate plutôt que des éléments sommables, vous récolterez des fatal error que vous n'aurez pas volés !
Si bien que j'en suis arrivé à une expérience de pensée transcendantale. Supposons que A et B soient des tableaux à deux dimensions dont chaque élément soit lui-même un tableau à deux dimensions. Hein ? Par exemple :
// On suppose que les variables internes désignent // des coordonnées numériques en x et y. var A = [ [xMin_A, yMin_A], [xMax_A, yMax_A] ]; var B = [ [xMin_B, yMin_B], [xMax_B, yMax_B] ];
On reconnaît ici une implémentation possible des structures de type “bounding box”, chaque boîte encapsulant des coordonnées minimum/maximum selon les deux axes. Il se trouve que pour vérifier le chevauchement ou l'inclusion géométrique de ces régions, on a besoin d'en calculer le milieu et/ou les dimensions, de soustraire les coordonnées deux à deux, etc.
Sans entrer dans les fioritures, posons la seule question qui vaille :
Est-ce que A + B a encore du sens ?
Si l'on reconsidère soigneusement la déclaration de l'opérateur + surchargé, il apparaît que les deux opérandes A et B satisfont le seul critère ontologique que nous ayons défendu corps et âme, à savoir que chacun est de toute évidence un tableau à deux éléments ! Alors la machine devrait comprendre A + B comme symboliquement équivalent à [ A[0]+B[0], A[1]+B[1] ]. Mais l'interpréteur va-t-il ruer dans les brancards ?
Nullement ! Car il se trouve que chacun des opérandes introduits dans cette aventure est lui-même un tableau à deux éléments — par exemple A[0] désigne [xMin_A, yMin_A] —, de sorte que rien n'empêchera l'interpréteur d'appliquer exactement les mêmes lois de composition.
Ce que nous venons de pressentir, c'est que la surcharge d'opérateur fonctionnera récursivement si les circonstances l'exigent et sous réserve qu'à chaque étape nous nous trouvions encore en présence d'un tableau à deux éléments sommables.
Un test dans IdExtenso permet de vérifier notre théorie sur des valeurs concrètes :
// 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
Comme prévu, le résultat obtenu est un tableau composé lui-même de deux tableaux à deux éléments. En termes d'économie d'écriture, l'expression A + B résume ici en trois symboles une addition infernale (plus de 70 symboles au total) que je vous laisse le soin de reconstituer d'ici les giboulées de mars...
V. aussi :
• $$.ArrayAs2D.jsxlib (IdExtenso module)
• IdExtenso, the scripting framework for InDesign ninjas
• Jouons avec les tableaux dans ExtendScript
• “Operator Overloading with ExtendScript”