When “different” is not enough: the story behind Diff(), DiffXT() and DiffXTT() in stzList
In Softanza, the question was more intentional:
by Mansour Ayouni · in the repository since 2025-12-25 · feature essay · area Collections & objects
In most programming libraries, diff is treated as a simple operation: compare two collections and list what is not the same.
What does it really mean for two lists to be different?
Not just technically different, but meaningfully different.
This reflection led to the design of a progressive diff mechanism in stzList, articulated in three deliberate levels: Diff(), DiffXT() and DiffXTT().
Each level answers a deeper question than the previous one.
Level 1 — Diff(): seeing what is different
The first level addresses the most immediate need:
Which items are not shared between the two lists?
o1 = new stzList([ "green", "red", "blue" ]) ? @@( o1.Common([ "yellow", "red", "blue", "gray" ]) ) #--> [ "red", "blue" ] ? @@( o1.Diff([ "yellow", "red", "blue", "gray" ]) ) #--> [ "green", "yellow", "gray" ]
run on 2026-10-08 20:43 at commit 4a184e6f0: kept its promise
Here:
Common()reveals what overlapsDiff()returns what belongs to only one side
This level is minimal, symmetric, and direct. It is ideal when you only need a factual answer, without interpretation.
Level 2 — DiffXT(): understanding how things differ
Very often, knowing what is different is not enough. The next natural question is:
Are these differences additions, removals, or modifications?
This is where XT — eXTended — comes into play.
? @@NL( o1.DiffXT([ "yellow", "red", "blue", "gray" ]) )
illustration
Result:
[ [ "added", [ "yellow", "gray" ] ], [ "removed", [ "green" ] ], [ "modified", [ ] ] ]
The diff now becomes expressive:
- Differences are classified
- The structure is stable and predictable
- Even empty categories are explicitly present
Level 3 — DiffXTT(): understanding why things differ
Some differences are neither pure additions nor pure removals. They are transformations.
To capture that idea, a further extension was introduced: XTT, yet another eXTension.
o1 = new stzList([ "green", [ "A", "B" ], "rediness", "blues" ]) ? @@NL( o1.DiffXTT([ "yellow", "red", [ "A" ], "blue", "gray" ]) )
illustration
Result:
[ [ "added", [ "yellow", "gray" ] ], [ "removed", [ "green" ] ], [ "modified", [ [ [ "A", "B" ], [ "A" ] ], [ "rediness", "red" ], [ "blues", "blue" ] ] ] ]
Here, the diff exposes relationships:
- A list evolving from
[ "A", "B" ]to[ "A" ] - Words reduced to their semantic core
- Elements that changed form but not intent
At this level, DiffXTT() no longer reports differences —
it explains them.
A deliberate progression, not increasing complexity
What matters most in this design is not the sophistication of the last level, but the freedom of choice it offers:
- Need speed and simplicity? →
Diff() - Need structured meaning? →
DiffXT() - Need transformation insight? →
DiffXTT()
Each level is intentional, additive, and optional.
Why this belongs in stzList
Although this mechanism later proved essential for higher-level structures — including graph comparisons — it belongs first and foremost to stzList.
Lists are the foundational abstraction of Softanza. By teaching lists how to explain their differences, the entire ecosystem gains expressive power.
In Softanza, even a simple list comparison can tell a story —
and Diff(), DiffXT() and DiffXTT() are precisely that:
narrators of change.
Cite
Mansour Ayouni. "When “different” is not enough: the story behind `Diff()`, `DiffXT()` and `DiffXTT()` in stzList". Softanza narrations, 2025. https://mayouni.github.io/stzsite/en/narrations/stzlist-diff.html
Run in Haro's name on 2026-10-08 20:43 inside the library at commit 4a184e6f0, block after block in one process: 1 of 3 blocks kept their promise; the others are illustrations. The code of the articles is Haro code. Where an article was written before the language took its present name, the name was changed and nothing else. Genre, area and series read from the file's name, the year from its first commit: derived, until the article carries its own header. The file on GitHub(opens in a new tab)

