Parenthesis and brace indexing operations #5

Open
opened 2025-10-11 03:28:57 +00:00 by UserCurt · 3 comments
UserCurt commented 2025-10-11 03:28:57 +00:00 (Migrated from codeberg.org)

MATLAB supports three main operations: dot, parenthesis, and brace. This feature request suggests extending from support of dot to the other two indexing operations. Notation should match that of MATLAB, namely using parenthesis for parenthesis operations and using braces for brace operations.

Some examples of parenthesis:

  • /A(1)
  • /B(2,3)
  • /C(:)
  • /D(:#1) -- Dimension specifiers can be given for indices
  • /E(:#1,:#2) -- This applies for each dimension separately
  • /F(3:5) -- Colon syntax should be support, similarly described in #2
  • /H([3:5 7 10]) -- Bracket syntax should be supported, similarly described in #2 and in this comment in #3

Some examples of brace:

  • /A{1}
  • /B{2,3}
  • /C{:}
  • /D{:#1} -- Dimension specifiers can be given to indices within brace dimensions

Given the similarity between parenthesis and brace operations, there should be large overlap in parsing and handling of these operations to keep code redundancy low and reuse high. One difference in MATLAB behavior is it allows for one to do X() but not X{}; it is unclear at this point if mpath should even support a zero-dimensional input. I am leaning towards mirroring MATLAB behavior because there could be edge cases with custom defined classes.

Brace with multiple indices would behave differently than if done in MATLAB. Normally, C{:} or C{1:2} would return a comma separated list by default, whereas mpath would not do this by default (unless you specify multiple outputs as described in #1). If this was not done this way, then /C{:}<:> would be a common pattern in mpath expressions without any upside from what I can tell.

It is currently unclear if resolve should automatically expand non-scalar values to have parenthesis or brace operations, like /A/B resolving to /A/B(:,:) if it is a matrix. For comparison, the behavior for comma separated list operation is to implicitly include <:> though only conditionally when listLength > 1. It would help with automatic assignment of dimensions as parenthesis could be prioritized in assignment order and equal to the correspond dimension. So in the example above, /A/B(:#1,:#2), or if there were to also be a glob wildcard, /*#3/B(:#1,:#2). But without special logical, the first two dimension would always automatically be assigned even for scalars because scalars are considered matrices (ndims being 2).

MATLAB supports three main operations: dot, parenthesis, and brace. This feature request suggests extending from support of dot to the other two indexing operations. Notation should match that of MATLAB, namely using parenthesis for parenthesis operations and using braces for brace operations. Some examples of parenthesis: - `/A(1)` - `/B(2,3)` - `/C(:)` - `/D(:#1)` -- Dimension specifiers can be given for indices - `/E(:#1,:#2)` -- This applies for each dimension separately - `/F(3:5)` -- Colon syntax should be support, similarly described in #2 - `/H([3:5 7 10])` -- Bracket syntax should be supported, similarly described in #2 and in [this comment](https://codeberg.org/UserCurt/mpath/issues/3#issuecomment-7670785) in #3 Some examples of brace: - `/A{1}` - `/B{2,3}` - `/C{:}` - `/D{:#1}` -- Dimension specifiers can be given to indices within brace dimensions Given the similarity between parenthesis and brace operations, there should be large overlap in parsing and handling of these operations to keep code redundancy low and reuse high. One difference in MATLAB behavior is it allows for one to do `X()` but not `X{}`; it is unclear at this point if mpath should even support a zero-dimensional input. I am leaning towards mirroring MATLAB behavior because there could be edge cases with custom defined classes. Brace with multiple indices would behave differently than if done in MATLAB. Normally, `C{:}` or `C{1:2}` would return a comma separated list by default, whereas mpath would not do this by default (unless you specify multiple outputs as described in #1). If this was not done this way, then `/C{:}<:>` would be a common pattern in mpath expressions without any upside from what I can tell. It is currently unclear if `resolve` should automatically expand non-scalar values to have parenthesis or brace operations, like `/A/B` resolving to `/A/B(:,:)` if it is a matrix. For comparison, the behavior for comma separated list operation is to implicitly include `<:>` though only conditionally when `listLength > 1`. It would help with automatic assignment of dimensions as parenthesis could be prioritized in assignment order and equal to the correspond dimension. So in the example above, `/A/B(:#1,:#2)`, or if there were to also be a glob wildcard, `/*#3/B(:#1,:#2)`. But without special logical, the first two dimension would always automatically be assigned even for scalars because scalars are considered matrices (`ndims` being 2).
UserCurt commented 2025-10-13 23:08:04 +00:00 (Migrated from codeberg.org)

MATLAB forbids using parenthesis indexing operation directly after parenthesis, like in A=1:3; A(2:3)(1). In addition, MATLAB forbits brace indexing operation directly after parenthesis indexing operation, like in B={3,4,5}; B(2:3){1}. It is undecided whether mpath should allow or disallow this behavior.

If decided to support this, the logic forming chunks of atomic index operations would need to have a separate chunk between these. For example, R=mpath.get(A, "(2:3)(1)") would be equivalent to the two-part operation sequence a=A(2:3); R=a(1). Similarly, R=mpath.get(B, "(2:3){1}") would be equivalent to the two-part operation sequence b=B(2:3); R=b{1}.

MATLAB forbids using parenthesis indexing operation directly after parenthesis, like in `A=1:3; A(2:3)(1)`. In addition, MATLAB forbits brace indexing operation directly after parenthesis indexing operation, like in `B={3,4,5}; B(2:3){1}`. It is undecided whether mpath should allow or disallow this behavior. If decided to support this, the logic forming chunks of atomic index operations would need to have a separate chunk between these. For example, `R=mpath.get(A, "(2:3)(1)")` would be equivalent to the two-part operation sequence `a=A(2:3); R=a(1)`. Similarly, `R=mpath.get(B, "(2:3){1}")` would be equivalent to the two-part operation sequence `b=B(2:3); R=b{1}`.
UserCurt commented 2025-10-13 23:32:33 +00:00 (Migrated from codeberg.org)

One consideration not discussed so far is the representation of indices in a string conversion of an mpath pointer after parsing an mpath expression. Representations are not unique.

The simplest approach would be to solely list the indices. I am unsure whether the comma should be included or not. Each of the following would display /A([1 2 3 4 5]):

mpath.Pointer("/A([1 2 3 4 5])")
mpath.Pointer("/A(1:5)")
mpath.Pointer("/A(1:1:5)")
mpath.Pointer("/A([1:5])")
mpath.Pointer("/A([1 2:5])")

Since colon is the most common operator, equally spaced items could be represented concisely. The above examples could be represented as /A(1:5). Concatenation would break the pattern, so mpath.Pointer("/A([1:5 10])") would resort to /A([1 2 3 4 5 10]).

Some combination of the above could be possible, though the details of the logic are not clear. Perhaps it can be done using some heuristics to determine the "simplest" representation of an array of numbers so that mpath.Pointer("/A([1 2 3 4 5])") would be represented as /A(1:5), and mpath.Pointer("/A([1:5 10])") would be represented as /A([1:5 10]).

One consideration not discussed so far is the representation of indices in a string conversion of an mpath pointer after parsing an mpath expression. Representations are not unique. The simplest approach would be to solely list the indices. I am unsure whether the comma should be included or not. Each of the following would display `/A([1 2 3 4 5])`: ```matlab mpath.Pointer("/A([1 2 3 4 5])") mpath.Pointer("/A(1:5)") mpath.Pointer("/A(1:1:5)") mpath.Pointer("/A([1:5])") mpath.Pointer("/A([1 2:5])") ``` Since colon is the most common operator, equally spaced items could be represented concisely. The above examples could be represented as `/A(1:5)`. Concatenation would break the pattern, so `mpath.Pointer("/A([1:5 10])")` would resort to `/A([1 2 3 4 5 10])`. Some combination of the above could be possible, though the details of the logic are not clear. Perhaps it can be done using some heuristics to determine the "simplest" representation of an array of numbers so that `mpath.Pointer("/A([1 2 3 4 5])")` would be represented as `/A(1:5)`, and `mpath.Pointer("/A([1:5 10])")` would be represented as `/A([1:5 10])`.
Owner

Commit e780864 removed the partial implementation of Paren and Brace operations in preparation for release v1. Earlier implementations remain available in commits e90335e and 419c4f3.

Commit `e780864` removed the partial implementation of `Paren` and `Brace` operations in preparation for release v1. Earlier implementations remain available in commits `e90335e` and `419c4f3`.
Sign in to join this conversation.
No description provided.