Ada-Rapporteur-Group / User-Community-Input

Ada User Community Input Working Group - Github Mirror Prototype
27 stars 1 forks source link

Properties lost by parenthesing an expression #44

Closed ARG-Editor closed 1 year ago

ARG-Editor commented 1 year ago

Tucker raised the question in AI22-0064-1 as to whether we intend properties to be lost by parenthesization of an expression (especially when that expression is a name of an object),

That is not a appropriate topic for that AI, but I did an extensive study to check where we're at in this regard. I concluded that there is no problem, but I thought that the answer wasn't so clear that I should just assume that answer, and it also would be good to preserve that work in the public record. Thus this Github Issue.

The current RM explicitly mentions the semantics of parenthesized expressions in many places. Parenthesized expressions (or a shortcut thereof) are explicitly mentioned many rules: 3.10.2(9/2), 3.10.2(32.4/4), 4.3.3(15/3), 3.9.2(3/5), 3.9.2(7/1), 3.9.2(18-18.1/2) [now changed, I think, to operative constituent], 6.1.1(22.8/5), 3.2.4(22/3), and 6.5.1(5.1/5). Operative constituent is mentioned in 4.3.2(5.1/5), the new 3.9.2(18), 6.2(10/5), 7.5(2.1/5), 3.10.2(16.1/5), and 4.5.9(6/5). Many of these rules go back to Ada 95 (and some to Ada 83).

These are all places where the properties of parenthesized expressions ARE defined. I think we have to assume that places that are omitted were done on purpose or because no one cared (the case never came up).

Of course, the missing definitions for the most basic semantics of a parenthesized expression (the type and how it is evaluated) muddle the answer somewhat. AI22-0064-1 was created specifically to define those cases, specifically, cases where ALL expressions have the property and thus it needs to be defined for all expressions. It was not intended to cover cases where some expressions don't have the property.

The reason that I think the omission of parenthesized expressions is intentional in many cases is the difference between a primary and a name.

A name represents an entity, and within an expression, it usually is representing an object. OTOH, a primary represents a value evaluated from something. Objects have many properties (such as aliasedness and variableness) that values do not have. Moreover, primaries are not syntactically allowed in most places where object properties are required. For instance, they cannot be given directly on the LHS of an assignment.

Of course, the situation is somewhat muddled, because there are easy ways to convert any arbitrary expression into a name (but not to preserve variableness).

So while the RM appears fairly self-consistent, we probably ought to re-assess what we want.

The most important language design principle here is that we want parenthesized expressions, conditional expressions, and declare expressions all work the same. Of those, the most important is clearly conditional expressions (they're the hardest to work around without changing the structure of the program; declare expressions can be eliminated with duplication, and parens around names can just be eliminated).

I don't think a general rule is possible. Allowing primaries to be variables would be inconsistent with the rest of the language, and we almost certainly do not want to be assigning into conditional expressions:

Natural'(if Foo then X else Y) := 10;

or better yet, combining this with the target symbol:

Natural'(if Foo then X else Y) := @ + 2;

Not allowing primaries (and conditional expressions) to be variables also eliminates the possibility of passing these to in out parameters.

Tucker raised the question of aliasedness, specifically in the case of aliased in parameters.

Aliased items are always objects as well as values. So it's clear that a conditional expression should only be treated as aliased if all of the dependent expressions are considered aliased. We surely don't want something like Natural'(if Foo then X else 2)'Access being legal. So this case means that we can't just use operative constituent, we have to say something about "all" somewhere.

We could still allow something like:

 procedure Foo (P : aliased in Natural; R : aliased in out Natural);

 Foo ((if Foo then X else Y), Z);

But allowing this would raise the question why the highly similar:

 Foo (Z, (if Foo then X else Y));

is not allowed. Moreover, the underlying model is that "aliased" requires the passing of an object. A primary is not an object, so why treat it as one? Finally, this looks like the sort of thing people would do mainly because they can, rather than it being a truly useful construct.

So I lean toward leaving this alone, and not allowing conditional expressions in these contexts.

Following our principles, that means that we don't want to allow parenthesized expressions or declare expressions, either.

To summarize, in the absence of compelling examples of usage, I think we want to stick with the principle that primaries are not objects, and thus do not have object properties. And we should wait to give more properties to conditional expressions (and parenthesized expressions and declare expressions) until something important is identified.

As always, comments and especially dissents welcome.

          Randy.
sttaft commented 1 year ago

I'm convinced. Parenthesized expressions are never aliased.

-Tuck

ARG-Editor commented 1 year ago

There doesn't seem to be anything for the ARG to do here, so I am closing this issue. - Randy