AdaCore / ada-spark-rfcs

Platform to submit RFCs for the Ada & SPARK languages
63 stars 28 forks source link

[RFC] new aggregate syntax #24

Closed raph-amiard closed 1 year ago

raph-amiard commented 5 years ago

Link to text: https://github.com/AdaCore/ada-spark-rfcs/blob/topic/new_aggregate_syntax/considered/rfc-new-aggregate-syntax.rst

sttaft commented 5 years ago

I would certainly see no reason to introduce "(...)" for a qualified expression. Rec'{...} and Container'[...] would be fine.

Don't forget the other kinds of aggregates, namely extension aggregates (presumably "{... with ...}") and delta aggregates (presumably "{... with delta ...}" for record deltas, and "[... with delta ...]" for array deltas).

QuentinOchem commented 5 years ago

Thanks for pushing this proposal @raph-amiard. This looks like a significant improvement over the initial ARG proposal to me for at least two reasons:

yannickmoy commented 5 years ago

I also find it exciting to fast-forward the language syntax in a way that is backwards compatible (you're not breaking any existing programs) but pushes in the direction of the new syntax (by making the old syntax obsolete and providing migration tools if possible).

I prefer this revision of the proposal to the initial one or the revision in PR#21 just closed by Quentin.

Then, I'd like also in a separate RFC to see indexing use square brackets!

sttaft commented 5 years ago

I find this proposal appealing, but I would prefer to move the record aggregate use of "{...}" into a separate proposal, which might be prototyped separately, just to allow us to get feedback independently. There is not really a problem with current record aggregates, so switching from "(...)" to "{...}" doesn't have as much value. Also, for folks coming from Python (or Java), using "{...}" for tuple-like things is potentially more confusing than sticking with "(...)".

I think the biggest value as far as being more "welcoming" of new users of Ada would be allowing "X[...]" for indexing, since this would look more familiar to essentially everyone coming from any other language. But I think that should also be a separate proposal, again to be able to get separate feedback. It certainly becomes easier to justify if we have added "[" and "]" to the Ada lexicon on behalf of container aggregates.

yannickmoy commented 5 years ago

Note @sttaft that the curly braces will allow writing {} instead of (null record) for an empty record and {X} instead of (Component => X} for a singleton. So I think it has value to simplify the adoption of Ada, in addition to the clarity it brings in the program textual form.

sttaft commented 5 years ago

One little datapoint on use of "[]" vs. "null." I looked at a CodePeer-like static analyzer for ParaSail written several years ago. In a 9000-line file, there were 70 assignments from an empty aggregate and 44 assignments from null. On the other hand, there were only 28 other uses of empty aggregates such as comparisons or passing as a parameter while there were 360 "others uses" of null. So in this container-heavy application, an empty aggregate was frequently used for initialization, on the same order as null, but was much less used for other things such as comparisons, presumably because there was a separate "Is_Empty" or "Length(C) > 0" way of determining if a container was empty, while "null" always appeared when checking whether a given value was null.

sttaft commented 5 years ago

Note @sttaft that the curly braces will allow writing {} instead of (null record) for an empty record and {X} instead of (Component => X} for a singleton. So I think it has value to simplify the adoption of Ada, in addition to the clarity it brings in the program textual form.

I do see this value, but would like to see it as a separate proposal, because unlike empty or singleton container aggregates, which are potentially useful for any container or unconstrained array type, an empty or singleton record is only useful for a null record or a singleton record type, respectively.

raph-amiard commented 5 years ago

I find this proposal appealing, but I would prefer to move the record aggregate use of "{...}" into a separate proposal, which might be prototyped separately, just to allow us to get feedback independently.

I think this proposal makes sense as a whole, so I don't want to split it. If you really want separate feedback, I suggest you make a separate RFC that doesn't include curly brackets, and link it to this one.

There is not really a problem with current record aggregates, so switching from "(...)" to "{...}" doesn't have as much value.

Two things:

  1. I think there is a problem, just not as big, as Yannick pointed out: empty records, and one elements records, have strange syntax rules for the moment, that would not be necessary anymore.
  2. One of the main points of this proposal is to remove syntactic ambiguity. Using the same notation for homogeneous/heterogeneous aggregates is one, so I think it's fundamental to this proposal.

Also, for folks coming from Python (or Java), using "{...}" for tuple-like things is potentially more confusing than sticking with "(...)".

  1. There is no "tuple like" thing in Ada. We have records, so waiting for a tuple data type, we don't have one. Of course you can use records where you would use tuples, but they're still records, not tuples.

  2. Every other statically typed Ada competitor uses "{}" for tuple and record-like things (C, C++, Java). Javascript, arguably a dynamic language that is even more used than python, uses {} for object literals. Haskell and OCaml use {} for records. Even in Python, you use {} for dicts, which are often used as records. So I think it's safe to say that there is wide precedent for this notation.

I think the biggest value as far as being more "welcoming" of new users of Ada would be allowing "X[...]" for indexing, since this would look more familiar to essentially everyone coming from any other language. But I think that should also be a separate proposal, again to be able to get separate feedback. It certainly becomes easier to justify if we have added "[" and "]" to the Ada lexicon on behalf of container aggregates.

Agreed that this would be great! Let's write an RFC :) I think this RFC should also, in line with the current one, make the "()" syntax obsolete.

ArnaudCharlet commented 5 years ago

If we're going to change the syntax and introduce [] (and {}) then I much prefer this proposal than the current Ada 2020 AI (212) because it's more consistent (both from an Ada point of view and from a "multi-language" point of view).

mosteo commented 5 years ago
  1. Of course you can use records where you would use tuples, but they're still records, not tuples.

(Sorry for the aside:) Which are cumbersome when members would be indefinite. I would expect tuples to be able to hold indefinites (just as indefinite alone values can be returned).

setton commented 5 years ago

I think this is going in the right direction! After reading this carefully, I find myself looking forward to the new syntax. Also definitely interest in what was put "to the future", ie using [] for indexing and allowing parenthesis for parameterless subprogram calls.

clairedross commented 5 years ago

This comment is not really about this RFC, but I think it should be considered here. How much do we want to deprecate existing syntax of Ada? I understand that we cannot go on adding new syntax without deprecating existing one, and that consistency is important for readability. But stability is important too. Backward incompatible changes are a real pain (yes I know, we are not there yet, we are only speaking about warnings). We should consider that existing Ada users (not those stuck at Ada 83, those asking for new features and enhancements) sometimes have big code bases, sometimes use code generators etc. I don't think we should completely refrain from deprecating Ada features when it is necessary, and this RFC is a perfect example of that. If we allow a new syntax for aggregates, we certainly don't want to keep the old one, so this RFC only stands if we consider deprecating the old syntax. But I think we should discuss and decide how much we want to allow changing the syntax, and weight in every cases the gain with respect to the cost.

sttaft commented 5 years ago

Based on current Ada practice, we move constructs into the "obsolescent features" annex (annex J), but require that they continue to be supported. The main goal of doing that is that a new user of the language need not read annex J. But we generally don't make existing programs using features of annex J illegal, unless the user specifies "pragma Restrictions(No_Obsolescent_Features);". Of course a vendor could provide other pragmas or command-line options to get warnings on use of obsolescent features. So I would interpret "deprecated" in this context, that is, we move the syntax and description into annex J, but you can continue to use the features as is unless you impose a "No_Obsolescent_Features" restriction on your project.

Take care, -Tuck

On Tue, Jul 30, 2019 at 5:38 AM Claire Dross notifications@github.com wrote:

This comment is not really about this RFC, but I think it should be considered here. How much do we want to deprecate existing syntax of Ada? I understand that we cannot go on adding new syntax without deprecating existing one, and that consistency is important for readability. But stability is important too. Backward incompatible changes are a real pain (yes I know, we are not there yet, we are only speaking about warnings). We should consider that existing Ada users (not those stuck at Ada 83, those asking for new features and enhancements) sometimes have big code bases, sometimes use code generators etc. I don't think we should completely refrain from deprecating Ada features when it is necessary, and this RFC is a perfect example of that. If we allow a new syntax for aggregates, we certainly don't want to keep the old one, so this RFC only stands if we consider deprecating the old syntax. But I think we should discuss and decide how much we want to allow changing the syntax, and weight in every cases the gain with respect to the cost.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AdaCore/ada-spark-rfcs/pull/24?email_source=notifications&email_token=AANZ4FNVGJF7ZUJEZ5J3I7LQCADZHA5CNFSM4IGKRN32YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3DM4MQ#issuecomment-516345394, or mute the thread https://github.com/notifications/unsubscribe-auth/AANZ4FP2UNXN43ESVRMUKPLQCADZHANCNFSM4IGKRN3Q .

jrcarter commented 5 years ago
  1. Terminology: ARM 2.1 defines the terms "left parenthesis" and "right parenthesis" for the characters '(' and ')', respectively. "Parenthesis" (plural "parentheses") is American usage, so we must also follow American usage of "bracket" to refer to the '[' and ']' characters and "brace" to refer to the '{' and '}' characters. There are no "curly brackets" in American usage, and "square brackets" is redundant.

  2. Comment on proposal: Having spent decades having to look at languages that use both parentheses and braces in this manner, I know that it is very easy to confuse them, and combining them makes the code harder to read and introduces hard-to-find errors. No well designed language would use both.

AdaDoom3 commented 5 years ago

I am in favor of this feature, but I disagree with the future possibility of having calls with no actuals getting a football and I think deprecating the current model could lead to problems.

yakobowski commented 5 years ago

I'm very much in favor of this proposal, which (IMO) reduces overloading in the language, and makes it more similar to other languages. (Getting towards uniformity is not always progress, but in this case I believe it is.) I also support the deprecation of the old syntax, as I find the new one much more consistent. My opinion is that it is actually possible in Ada to deprecate syntax, given that

raph-amiard commented 5 years ago

@AdaDoom3

having calls with no actuals getting a football

What does "getting a football" mean ? :confused:

and I think deprecating the current model could lead to problems

Even if that's beyond the scope of this PR, could you possibly expand on that somewhere ? I'd be interested in knowing your objections :)

sttaft commented 5 years ago

I am guessing that to some people (Americans or Australians, I would guess), "()" looks like a "football." In Europe it looks like a deflated football standing on its end ... ;-)

-Tuck

On Wed, Aug 7, 2019 at 6:46 AM Raphaël AMIARD notifications@github.com wrote:

@AdaDoom3 https://github.com/AdaDoom3

having calls with no actuals getting a football

What does "getting a football" mean ? 😕

and I think deprecating the current model could lead to problems

Even if that's beyond the scope of this PR, could you possibly expand on that somewhere ? I'd be interested in knowing your objections :)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AdaCore/ada-spark-rfcs/pull/24?email_source=notifications&email_token=AANZ4FLFQQCT3EKV23GCTYTQDKRZXA5CNFSM4IGKRN32YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3X72SA#issuecomment-519044424, or mute the thread https://github.com/notifications/unsubscribe-auth/AANZ4FLPC76JI25FHWKOWFLQDKRZXANCNFSM4IGKRN3Q .

raph-amiard commented 5 years ago

No well designed language would use both.

@jrcarter Please refrain from stating subjective preferences as objective truths, especially when those imply that a number of widely used/appreciated languages are "not well designed" . Thanks :slightly_smiling_face:

raph-amiard commented 5 years ago

I am guessing that to some people (Americans or Australians, I would guess), "()" looks like a "football." In Europe it looks like a deflated football standing on its end ... ;-)

Hah :) Got it ! thanks !

jrcarter commented 5 years ago

raph-amiard: The overwhelming majority of "widely used/appreciated languages" are demonstrably not well designed.

jrcarter commented 5 years ago

We should remember that Ada 80 required an empty set of parentheses as the parameter list for a subprogram/entry call with no explicit actual parameters. This was widely derided during the public review process and was removed in Ada 83.

yannickmoy commented 5 years ago

@jrcarter interesting bit of history! which shows that what was true 40 years ago is not necessarily true today. The empty parentheses for a call serve as a useful automatic trigger to alert programmers/reviewers of the presence of a call, and most languages rightfully IMO use that token to signal calls. That Ada does not need it for disambiguation does not mean it's a good choice.

raph-amiard commented 5 years ago

@jrcarter

We should remember that Ada 80 required an empty set of parentheses as the parameter list for a subprogram/entry call with no explicit actual parameters. This was widely derided during the public review process and was removed in Ada 83.

It would be good to have a source for that. It seems particularly weird given that the reference manual from Honeywells/Ichbiah's Green language (see here: https://ia800805.us.archive.org/7/items/DTIC_ADA073661/DTIC_ADA073661.pdf, page 29) already used the same syntax as current Ada, ie. no parentheses. On the other hand I couldn't find any source for what you're saying here.

Which in any case isn't a rational argument one way or the other anyway: We don't really care about if it was "derided" or not. We care about why, which is lacking from your message.

Which is also lacking in your last statement

The overwhelming majority of "widely used/appreciated languages" are demonstrably not well designed.

Yet again you fail to demonstrate.

In that light, I will ask you again: Please refrain from stating your opinions as objective truths. If you have a point to make, please make an effort to provide a rationale for it. If you're not willing to meet those standards, this GitHub is not the right place to discuss. What we want here is a reasoned and respectful discussion about programming language design. You're providing neither so far. Thanks in advance for your efforts and comprehension.

jrcarter commented 5 years ago

I seem to have misremembered: Ada 80 only required the empty parentheses for function calls. The ARM-80 is at https://archive.org/details/mil-std-ada. Section 6.4 on page 6-5 has the syntax for subprogram calls indicating that function calls either have actual parameters or "()". Interesting how it differs from that version of Green.

sttaft commented 5 years ago

It's worth remembering that Pascal was the starting point for essentially all of the languages in the DoD-1 competition, which ended with Jean Ichbiah's "Green" language being chosen, which was ultimately named "Ada" in honor of Lady Ada Lovelace. So Pascal conventions were often adopted in the absence of a recognized problem with Pascal. One example of a perceived problem with Pascal was that ";" was a separator rather than a terminator of statements -- in all of the DoD-1 languages I believe ";" was adopted as a terminator. But things like whether parameterless calls needed "()" was inherited from Pascal, where I believe parameterless procedure calls do not use "()" while functions do. Sometime between 1980 and 1983 enumeration literals were re-imagined as parameterless functions, and clearly no one wanted to write "()" after each enumeration literal. This might have contributed to the decision to drop "()" in general on parameterless function calls.

In general there was a desire to syntactically merge notions in Ada 83, where array indexing, conversion, and function calls all use the "name(arg1, arg2, ...)" syntax. Merging enumeration literals and parameterless function calls was somewhat along the same lines. Personally, I think requiring empty parentheses for parameterless function calls would be somewhat of an earthquake at this point, and the benefit of being explicit probably does not exceed the disruption costs. But of course your mileage may vary! -Tuck

On Tue, Aug 13, 2019 at 11:52 AM Jeffrey R. Carter notifications@github.com wrote:

I seem to have misremembered: Ada 80 only required the empty parentheses for function calls. The ARM-80 is at https://archive.org/details/mil-std-ada. Section 6.4 on page 6-5 has the syntax for subprogram calls indicating that function calls either have actual parameters or "()". Interesting how it differs from that version of Green.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AdaCore/ada-spark-rfcs/pull/24?email_source=notifications&email_token=AANZ4FIMHWHVYDZSYNNZ623QELKETA5CNFSM4IGKRN32YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4GDNZQ#issuecomment-520894182, or mute the thread https://github.com/notifications/unsubscribe-auth/AANZ4FKIEZQJR3MLGWIS66DQELKETANCNFSM4IGKRN3Q .

jrcarter commented 5 years ago

sttaft wrote:

But things like whether parameterless calls needed "()" was inherited from Pascal, where I believe parameterless procedure calls do not use "()" while functions do.

Pascal does not reuire "()" for function calls without parameters. I was a Pascal user when I encountered Ada 80 and I thought the empty parentheses looked odd. So that's not where Ada 80 got the notation from. One thing I note about them is that some function calls that would be ambiguous in Ada 83 would not be in Ada 80. Perhaps that's why they were added. Pascal was a popular language at the time, which might help explain why they were disliked. Not wanting to put "()" after enumeration literals sounds plausible, too.

sttaft commented 5 years ago

Thanks for clarifying. So ultimately Ada 83 adopted Pascal's parameterless call syntax for both functions and procedures.

-Tuck

On Wed, Aug 14, 2019 at 12:05 PM Jeffrey R. Carter notifications@github.com wrote:

sttaft wrote:

But things like whether parameterless calls needed "()" was inherited from Pascal, where I believe parameterless procedure calls do not use "()" while functions do.

Pascal does not reuire "()" for function calls without parameters. I was a Pascal user when I encountered Ada 80 and I thought the empty parentheses looked odd. So that's not where Ada 80 got the notation from. One thing I note about them is that some function calls that would be ambiguous in Ada 83 would not be in Ada 80. Perhaps that's why they were added. Pascal was a popular language at the time, which might help explain why they were disliked. Not wanting to put "()" after enumeration literals sounds plausible, too.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AdaCore/ada-spark-rfcs/pull/24?email_source=notifications&email_token=AANZ4FNL3RX2VE2YCOFSB53QEQUMFA5CNFSM4IGKRN32YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4JJDBI#issuecomment-521310597, or mute the thread https://github.com/notifications/unsubscribe-auth/AANZ4FNR2R3IDJWEJMG6MF3QEQUMFANCNFSM4IGKRN3Q .

raph-amiard commented 1 year ago

Not up to date anymore. If proposal is reconsidered, a new RFC will be written, taking into account the current stage of things in GNAT/Ada.