qt4cg / qtspecs

QT4 specifications
https://qt4cg.org/
Other
28 stars 15 forks source link

Arrays and maps: Members, entries, values, contents, pairs, … #1338

Open ChristianGruen opened 2 months ago

ChristianGruen commented 2 months ago

With version 4.0, we are adding a lot of promising and powerful new map and array features. This is a big step forward, compared to the obvious limitations of 3.1.

Some aspects of the 3.1 design have made it difficult (or impossible) to fully adjust array and maps, but (in my opinion) the old overall concept was impressively consistent – and it is definitely a big challenge to achieve a 4.0 design that is not too fragmented.

To me, this becomes particularly evident in the case of arrays. The following example sums up the items of all members of an array. For the cumbersome 3.1 solution…

for $pos in 1 to array:size($array)
return sum($array($pos))

…we now have at least several (roughly?) equivalent options to do this; for example…

  1. for member $m in $array return sum($m)
  2. array:members($array) ! sum(?value)
  3. $array?entry::* ! sum(?value)
  4. $array?value::* ! sum(.)

…which is great – but the downside is that we have introduced a terminological jungle. The examples above could imply that:

Next, with the current proposals, $array:content::1 gives us the sequence-concatenated version of the first member of an array. Similar observations can be made with maps: map:entries($map) returns singleton maps, whereas $map?entry::* is actually equivalent to map:pairs.

The fundamental obstacle are clear have already been discussed a lot, but I think that with each new concept, we should try really hard not to blur terminology, and work with terms that users can assign to the underlying concepts without too much guessing or trial’n’error.

My general suggestions would be to…

  1. align the new lookup terminology and the builtin functions, and
  2. omit, rename or drop builtin functions that do not rely on the existing or arising terminology.

My concrete proposals (maybe followed by others) would be to…

  1. As we already have map:pairs, $map-or-array?entry::* should become $map-or-array?pair::*, and we should add a array:pairs function, and probably array:of-pairs (see #832). We shouldn’t do it the other way round and rename map:pairs to map:entries, as the existing map:entry function returns a singleton map.
  2. If we keep calling the sequence-concatenated result “content”, we should include it in the definition of sequence-concatenation. In addition, (array|map):values should be renamed to (array|map):contents (see #1179).
  3. Due to the existence of array:value::*, we should make clear what an “array value” is, how it it positions itself in relation to an “array member”, and we should add map:values and array:values for equivalent results.
  4. Due to the existence of array:key::*, we should add a array:keys function (which returns a dense integer range). 1 to array:size($array) could then be written as array:keys($array).
  5. As we have map:entries and map:merge, we could add equivalent array:entries and array:merge functions.
  6. I would suggesting dropping array:members/array:of-members in favor of either array:split/array:join, array:pairs/array:of-pairs (see 1.) or array:entries/array:merge (see 5). I have a strong conviction that an “array member“ should not be a map; an “array pair” or ”array entry” certainly could.

One might question if we should really introduce map terminology for arrays. I think we have no other chance if we want to treat maps and arrays identically with lookup key specifiers, and it may help us later on to treat both data structures as similar as possible.

ChristianGruen commented 2 weeks ago

In https://github.com/qt4cg/qtspecs/issues/1457#issuecomment-2360628218, I found cases in which “map keys” and “array indexes” are mentioned. I think it gets more and more confusing to respect the differences between maps and arrays, and analogous to array:key::*, I would be happy if we treated array index values as keys (adding an array:keys function, as suggested in this issue, would support this approach).