Delimiter for intentionally separating atomic operations #28

Closed
opened 2025-10-14 00:37:49 +00:00 by UserCurt · 2 comments
UserCurt commented 2025-10-14 00:37:49 +00:00 (Migrated from codeberg.org)

This issue proposes the introduction of a delimiter to the syntax that has the purpose to separate atomic operations (those built into MATLAB). This can be important in edge cases for custom classes implementing custom indexing operations. For some explanatory background:

When applying a series of dot, parenthesis, and brace operations to access (reference) a value on, for example, a custom class implementing matlab.mixin.indexing.RedefinesDot, matlab.mixin.indexing.RedefinesParen and matlab.mixin.indexing.RedefinesBrace, MATLAB calls dotReference, parenReference, or braceReference, respectively, through a single method call. This is important because it means MATLAB does not recursively call operation; A series of dot, parenthesis, and brace operations act as a single operation! It can depend on the implementation within this custom class whether this single series of operations behaves the same or differently than if performing each operation separately or if they were chunked differently. Below is an example using a hypothetical custom class MyClass where the resulting value for y1, y2, and y3 are not necessarily the same.

% Dot, Brace, Paren
y1 = MyClass.A{2,3}(4,:);

% Dot, Brace; Paren
temp = MyClass.A{2,3};
y2 = temp(4,:);

% Dot; Brace, Paren
temp = MyClass.A;
y3 = temp{2,3}(4,:);

Current behavior in mpath is to group as many of these "atomic operations" together, so mpath.get(MyClass, "/A{2,3}(4,:)") would return the same value as y1. If having y2 and y3 be different was intentional behavior for MyClass, there is currently not an elegant way to get these desired values this with a single mpath expression. The current work-around would be to use CommaSeparatedList (non-atomic) operator to select the first output using <1>. For example, y2 could be obtained using mpath.get(MyClass, "/A{2,3}<1>(4,:)"), and y3 could be obtained using mpath.get(MyClass, "/A<1>{2,3}(4,:)").

This issue proposes introducing a new syntax, a delimiter between atomic operations, for intentionally separating these atomic operations without using the CommaSeparatedList operation. Some proposed syntax options include:

  • /A/B<>/C/D
  • /A/B|/C/D
  • /A/B'/C/D
  • /A/B`/C/D
  • /A/B:/C/D
  • /A/B./C/D
  • /A/B,/C/D
  • /A/B;/C/D

Usage of <> is nice because it mirrors the current work-around while omitting any indices, but it requires two wide characters and takes a lot of space. I personally like the syntax options that "look small" because this operation is a "small" operation in some sense, it doesn't do anything except break up the atomic operations.

If there is more than one output at the point where this delimiter appears, this should give an error.

This issue proposes the introduction of a delimiter to the syntax that has the purpose to separate atomic operations (those built into MATLAB). This can be important in edge cases for custom classes implementing custom indexing operations. For some explanatory background: When applying a series of dot, parenthesis, and brace operations to access (reference) a value on, for example, a custom class implementing [matlab.mixin.indexing.RedefinesDot](https://www.mathworks.com/help/matlab/ref/matlab.mixin.indexing.redefinesdot-class.html), [matlab.mixin.indexing.RedefinesParen](https://www.mathworks.com/help/matlab/ref/matlab.mixin.indexing.redefinesparen-class.html) and [matlab.mixin.indexing.RedefinesBrace](https://www.mathworks.com/help/matlab/ref/matlab.mixin.indexing.redefinesbrace-class.html), MATLAB calls `dotReference`, `parenReference`, or `braceReference`, respectively, through a _single_ method call. This is important because it means MATLAB does not recursively call operation; A series of dot, parenthesis, and brace operations act as a single operation! It can depend on the implementation within this custom class whether this single series of operations behaves the same or differently than if performing each operation separately or if they were chunked differently. Below is an example using a hypothetical custom class `MyClass` where the resulting value for `y1`, `y2`, and `y3` are not necessarily the same. ```matlab % Dot, Brace, Paren y1 = MyClass.A{2,3}(4,:); % Dot, Brace; Paren temp = MyClass.A{2,3}; y2 = temp(4,:); % Dot; Brace, Paren temp = MyClass.A; y3 = temp{2,3}(4,:); ``` Current behavior in mpath is to group as many of these "atomic operations" together, so `mpath.get(MyClass, "/A{2,3}(4,:)")` would return the same value as `y1`. If having `y2` and `y3` be different was intentional behavior for `MyClass`, there is currently not an elegant way to get these desired values this with a single mpath expression. The current work-around would be to use CommaSeparatedList (non-atomic) operator to select the first output using `<1>`. For example, `y2` could be obtained using `mpath.get(MyClass, "/A{2,3}<1>(4,:)")`, and `y3` could be obtained using `mpath.get(MyClass, "/A<1>{2,3}(4,:)")`. This issue proposes introducing a new syntax, a delimiter between atomic operations, for intentionally separating these atomic operations without using the CommaSeparatedList operation. Some proposed syntax options include: - `/A/B<>/C/D` - `/A/B|/C/D` - `/A/B'/C/D` - ``/A/B`/C/D`` - `/A/B:/C/D` - `/A/B./C/D` - `/A/B,/C/D` - `/A/B;/C/D` Usage of `<>` is nice because it mirrors the current work-around while omitting any indices, but it requires two wide characters and takes a lot of space. I personally like the syntax options that "look small" because this operation is a "small" operation in some sense, it doesn't do anything except break up the atomic operations. If there is more than one output at the point where this delimiter appears, this should give an error.
UserCurt commented 2025-10-14 00:39:29 +00:00 (Migrated from codeberg.org)

A very closely related but separate option is to have a named argument that forces every atomic operation to be treated separately, as if a delimiter was present between every atomic operation. This would give a little more control to the user, but not much.

A very closely related but separate option is to have a named argument that forces every atomic operation to be treated separately, as if a delimiter was present between every atomic operation. This would give a little more control to the user, but not much.
UserCurt commented 2025-10-14 00:45:25 +00:00 (Migrated from codeberg.org)

Ultimately, I decided this proposal will be rejected as it is quite the uncommon edge case. I have never seen behavior where accessing a class in these few different ways would intentionally give different results. I don't think the added benefit of dedicating a new character in the syntax warrants developer time and implementation costs for little benefit.

If you find yourself in this very unlikely scenario while using mpath, I advise using the above-presented workaround of using the CommaSeparatedList with index 1 to force breaking up atomic operations. In the examples above, this would be /A{2,3}<1>(4,:) and /A<1>{2,3}(4,:).

Ultimately, I decided this proposal will be rejected as it is quite the uncommon edge case. I have never seen behavior where accessing a class in these few different ways would intentionally give different results. I don't think the added benefit of dedicating a new character in the syntax warrants developer time and implementation costs for little benefit. If you find yourself in this very unlikely scenario while using mpath, I advise using the above-presented workaround of using the CommaSeparatedList with index 1 to force breaking up atomic operations. In the examples above, this would be `/A{2,3}<1>(4,:)` and `/A<1>{2,3}(4,:)`.
Sign in to join this conversation.
No description provided.