--- ai05s/ai05-0158-1.txt 2011/11/01 05:32:52 1.17 +++ ai05s/ai05-0158-1.txt 2011/12/31 06:59:38 1.18 @@ -145,7 +145,7 @@ AARM To Be Honest: X not in A | B | C is intended to be exactly equivalent to not (X in A | B | C), including in the order of evaluation of the simple_expression -and membership_choices. +and membership_choices. Replace 4.9(11) [definition of a static expression] @@ -230,19 +230,19 @@ An @i<expression> is a formula that defines the computation or retrieval of a value. In this International Standard, the term "expression" refers to a construct of the syntactic category @fa<expression> or of any of the following -categories: @fa<choice_expression>, @fa<choice_relation>, @fa<relation>, +categories: @fa<choice_expression>, @fa<choice_relation>, @fa<relation>, @fa<simple_expression>, @fa<term>, @fa<factor>, @fa<primary>, @fa<conditional_expression>, @fa<quantified_expression>. !corrigendum 4.4(2) @dinsa -@xcode<@fa<expression ::= +@xcode<@fa<expression ::= relation {>@ft<@b<and>>@fa< relation} | relation {>@ft<@b<and then>>@fa< relation} | relation {>@ft<@b<or>>@fa< relation} | relation {>@ft<@b<or else>>@fa< relation} | relation {>@ft<@b<xor>>@fa< relation}>> @dinss -@xcode<@fa<choice_expression ::= +@xcode<@fa<choice_expression ::= choice_relation {>@ft<@b<and>>@fa< choice_relation} | choice_relation {>@ft<@b<or>>@fa< choice_relation} | choice_relation {>@ft<@b<xor>>@fa< choice_relation} @@ -255,7 +255,7 @@ !corrigendum 4.4(3) @drepl -@xcode<@fa<relation ::= +@xcode<@fa<relation ::= simple_expression [relational_operator simple_expression] | simple_expression [>@ft<@b<not>>@fa<] >@ft<@b<in>>@fa< range | simple_expression [>@ft<@b<not>>@fa<] >@ft<@b<in>>@fa< subtype_mark>> @@ -322,7 +322,7 @@ !corrigendum 4.5.2(28) @drepl -A membership test using @b<in> yields the result True if: +A membership test using @b<in> yields the result True if: @dby An @i<individual membership test> yields the result True if: @@ -2108,7 +2108,7 @@ From: Robert Dewar Date: Saturday, November 13, 2010 5:21 AM -> Either an English language rule should be introduced to fix the +> Either an English language rule should be introduced to fix the > grammar change, or the grammar should simply use the original productions: I prefer the original productions, I don't like an english language rule here, @@ -2129,5 +2129,647 @@ The grammar change is OK. It will be treated as an editorial fix (this AI was previously approved). + +**************************************************************** + +From: Yannick Moy +Date: Tuesday, March 29, 2011 7:39 AM + +With the current wording of AI05-0158-1 (membership tests), it is allowed to +write + + X in Y + +as a synonym for + + X = Y + +for X and Y values of an arbitrary type. + +This does not improve readability, and could easily be rejected by the standard. +This is what I am proposing. + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 8:33 AM + +I think this suggestion is + +a) too late +b) wrong in any case + +I think it would be odd to special case the case of one element, and see no +reason to do so, we don't go out of our way to special case things and disallow +them just because they generate unnecessary duplications, e.g. + + (if B then true else false) + +is not rejected, even though many people would think that writing simply B would +be more readable. If they think that, let them write B! Similarly in this case, +if you think that X = Y is more readable than X in Y, then write X = Y. + +For me a situation like + + type Day is (Sun, Mon, Tue ....); + + Rest_Day : constant Day := Sun; + subtype Donut_Day is Day range Tue .. Wed; + +is reasonable, and then it seems fine to say + + if D in Rest_Day .. + + if D in Donut_Day ... + +at that level of abstraction, it really does not matter that Rest_Day is a +singleton .. yes you could have written Rest_Day as a singleton subtype, but I +see no reason to force that. + +**************************************************************** + +From: Tucker Taft +Date: Tuesday, March 29, 2011 9:29 AM + +... +> This does not improve readability, and could easily be rejected by the +> standard. This is what I am proposing. + +Sounds like a good proposal. We don't need another situation where there are +two almost-equivalent ways to do the same thing! + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 9:57 AM + +Well that's a surprising turn .. I guess we have to ask other ARG members +whether they want to introduce this special case restriction (I am strongly +opposed :-)) + +**************************************************************** + +From: Bob Duff +Date: Tuesday, March 29, 2011 9:54 AM + +> Sounds like a good proposal. We don't need another situation where +> there are two almost-equivalent ways to do the same thing! + +I have no strong opinion on this, but there is some value in uniformity with +case statements. I must admit that when Yannick first pointed out that "X in Y" +was being accepted by GNAT (Y not a subtype), I thought it was a compiler bug. +;-) + +**************************************************************** + +From: Tucker Taft +Date: Tuesday, March 29, 2011 10:14 AM + +I don't think anyone ever intended for a single variable to be interpreted as a +set. I agree that "A | B" is a set, but I don't think simply "A" should be +treated as a set for the purposes of membership testing. + +If there were some kind of set bracketing notation, such as "{...}" +then I would agree that one item would not be a special case. +But without some kind of special "set" brackets, I think users will be +seriously confused by "X in Y" meaning "X = Y". I could imagine "X in Y" meaning +"X in Y'Range" or something like that. That kind of potential confusion is not +helpful. + +Note that there is already a precedent for requiring two or more items in a list +for it to be interpreted as a composite object. In particular, "(Y)" means +parenthesized Y, while "(Y, Z)" is a two-element aggregate with components Y and +Z. + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 10:28 AM + +> I don't think anyone ever intended for a single variable to be +> interpreted as a set. I agree that "A | B" is a set, but I don't +> think simply "A" should be treated as a set for the purposes of +> membership testing. + +Well I most certainly thought this was the intention, so the above claim is too +strong. + +> If there were some kind of set bracketing notation, such as "{...}" +> then I would agree that one item would not be a special case. +> But without some kind of special "set" brackets, I think users will +> be seriously confused by "X in Y" meaning "X = Y". +> I could imagine "X in Y" meaning "X in Y'Range" or something like +> that. That kind of potential confusion is not helpful. +> +> Note that there is already a precedent for requiring two or more items +> in a list for it to be interpreted as a composite object. In +> particular, "(Y)" means parenthesized Y, while "(Y, Z)" is a +> two-element aggregate with components Y and Z. + +Well I find myself somewhat convinced by this, I think I still prefer the status +quo, and that is what GNAT implements now, but I could live with the idea that +there must be at least two elements for this treatment to apply. + +**************************************************************** + +From: Steve Baird +Date: Tuesday, March 29, 2011 11:08 AM + +> Well that's a surprising turn .. I guess we have to ask other ARG +> members whether they want to introduce this special case restriction +> (I am strongly opposed :-)) + +There are good arguments on both sides, so I don't feel strongly about this one +- I could live with either alternative. + +Still, I agree with Robert and disagree with Tuck for three reasons. + +1) A corner case. + +If "=" resolves to a user-defined "=" function, then X = Foo is not the same as +X in Foo. AI05-0158 says: + + If the tested type is a record type or a limited type, the test + uses the primitive equality for the type; otherwise the test + uses predefined equality. + +==== + +2) Regularity. If I have something like + + Membership_Table : constant Boolean_Array := + (X in Enum_Lit1 | Enum_Lit2 | Subtype3, + X in Subtype4, + X in Enum_Lit5 | Subtype6, + X in Enum_Lit7, + X in Subtype8); + +, it would look odd to have to change the 4th element of this table. + +==== + +3) Maintainability. I recently went through the exercise of "splitting" +an enumeration literal, as in changing + + type T is (Aaa, Bbb, Ccc); +to + type T is (Asa, Bbb_1, Bbb_2, Ccc); + subtype Bbb is Bbb_1 .. Bbb_2; + +In almost all (but not all) cases, I wanted the two values to be treated in th +same way that that the one value had been treated. + +Allowing "X in Bbb" to work in either case might help with this sort program +transformation. + +==== + +I'm not claiming that any of these reasons are particularly compelling, but in +my mind they are enough to tip the balance. + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 11:14 AM + +Yes, I find these arguments convincing + +**************************************************************** + +From: Randy Brukardt +Date: Tuesday, March 29, 2011 1:11 PM + +> I have no strong opinion on this, but there is some value in +> uniformity with case statements. + +That's pretty much my opinion -- I don't care that much, but I think I prefer +this to match case statements exactly. The two ways to do one thing is overrated +(I can't remember any programming language that doesn't have that: consider X * +2 vs. X + X) -- it's all about maximizing understandability and readability. + +**************************************************************** + +From: Dan Eilers +Date: Tuesday, March 29, 2011 1:19 PM + +> This does not improve readability, and could easily be rejected by the standard. +> This is what I am proposing. + +I agree with Yannick that Z in Y, where Y is an element, should be rejected on +the grounds that it is a confusing construct, since set theory normally makes a +clear distinction between an element and a set with one element. + +**************************************************************** + +From: Bob Duff +Date: Tuesday, March 29, 2011 2:00 PM + +Note that you can say "Z in (Y)", but not "Z in (Y | X)". +Nor, for that matter, "Z in ()". + +**************************************************************** + +From: Randy Brukardt +Date: Tuesday, March 29, 2011 2:03 PM + +> I agree with Yannick that Z in Y, where Y is an element, should be +> rejected on the grounds that it is a confusing construct, since set +> theory normally makes a clear distinction between an element and a set +> with one element. + +I'm puzzled. I don't disagree about the set theory comment, but it seems +irrelevant. Ada also makes a clear (if subtle) distinction between an element +and a set with one element. In + Z = Y +Y is a single element, while in + Z in Y +Y is a set with a single element. There are no contexts where both a set and a +single value are allowed, so there can be no confusion. + +This is no different than the situation with case statements, "when" +introduces a set there. + +I think you could make the argument that Ada should make the use of sets clearer +(say with a notation like "()" or "{}"), and I did try to make that argument at +one point, but it lost out to consistency with case statements (also a +reasonable choice IMHO). There has been little interest in more general support +for sets, and we would really need that in order to justify a dedicated +notation. + +But I don't see any difference between + Z in Y +and + Z in X | Y +and + when Y => +and + when X | Y => + +These are all representations of sets. Why anyone would think that there is +something different about the first escapes me. + +**************************************************************** + +From: Dan Eilers +Date: Tuesday, March 29, 2011 2:17 PM + +> ... Ada also makes a clear (if subtle) distinction +> between an element and a set with one element. In +> Z = Y +> Y is a single element, while in +> Z in Y +> Y is a set with a single element. There are no contexts where both a +> set and a single value are allowed, so there can be no confusion. + +The confusion is that a set-membership operator is used where the rhs is not a +set, so the reader is left wondering whether the writer intended to write +something else, or just used an odd way to say Z = Y. + +> But I don't see any difference between +> Z in Y +> and +> Z in X | Y +> and +> when Y => +> and +> when X | Y => + +The difference is that there's no explicit set-membership operator, so the +reader isn't puzzled about why a set-membership operator is used without a set. + +**************************************************************** + +From: Randy Brukardt +Date: Tuesday, March 29, 2011 2:46 PM + +> The confusion is that a set-membership operator is used where the rhs +> is not a set, so the reader is left wondering whether the writer +> intended to write something else, or just used an odd way to say Z = +> Y. + +But the RHS *is* a set here. The RHS of "in" is always a set. There is no such +thing "as a set operator where the RHS is not a set". + +There is a confusion possible in that the syntax for a set is null (there is no +syntax specifically for a set). That is, the syntax for a set with one element +is the same as the syntax for one expression. + +But probably the real problem is calling "in" a set membership operator. Ada +doesn't have sets, and talking about them only confuses things. "In" is +officially the "membership operation" -- "set" does not appear! + +And I personally would consider this membership in a "list"; '|' is a list +separator - it doesn't have anything to do with sets (think about the other uses +of '|'): + X in Y | Z | W -- List of length three + X in Y | Z -- List of length two + X in Z -- List of length one + +I really don't see any sets here at all. As you note, we'd need syntax to define +a set, and Ada doesn't have such a syntax - on purpose. As such, Ada has no sets +and talking about sets at all only confuses the issues. + +**************************************************************** + +From: Dan Eilers +Date: Tuesday, March 29, 2011 3:24 PM + +> That is, the syntax for a set with one element is the same as the +> syntax for one expression. + +This is the crux of my objection. In set theory, you would not want the syntax +to be the same for two things which are semantically distinct. + +> I really don't see any sets here at all. + +It doesn't really matter whether you are calling it set theory or list theory, +the concern remains that confusion is possible when semantically distinct things +are syntactically indistinguishable. + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 4:16 PM + +> It doesn't really matter whether you are calling it set theory or list +> theory, the concern remains that confusion is possible when +> semantically distinct things are syntactically indistinguishable. + +I agree with this in principle, but I see no case of it here! +What are the semantically distinct things that are syntactically +indistinguisable, please illustrated your answer with exact Ada code, don't just +speak in generalities. + +**************************************************************** + +From: Tucker Taft +Date: Tuesday, March 29, 2011 3:05 PM + +I can certainly learn to live with it. +In fact, since operators are not by default directly visible, I suspect that +with this change we will see some new idioms emerge, including: + + while Ptr not in null loop + ... + Ptr := Ptr.Next; + end loop; + +avoiding the need for that pesky "use type Blah;" + +**************************************************************** + +From: Yannick Moy +Date: Tuesday, March 29, 2011 4:30 PM + +If you ask me, the above is strictly less readable than + + while Ptr /= null loop + +But the point is rather, like Dan said, that the same variable Y can be either +an element of type T or a set of elements of T depending on the context: + X in Y + X = Y + +I find this at odds with Ada, because this kind of overloading is new in Ada. +This is not intuitive, and does not bring much, so I don't like it. + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 4:43 PM + +> If you ask me, the above is strictly less readable than +> +> while Ptr /= null loop + +You miss Tuck's point, the not in null idiom avoids the need for the very ugly +"use type Blah;" or even worse some claptrap prefix notation. For those who +eschew the use of even use type clauses, we definitely prefer + + while Ptr not in null loop + +> But the point is rather, like Dan said, that the same variable Y can +> be either an element of type T or a set of elements of T depending on the context: +> X in Y +> X = Y + +But there are no sets here, the word "set" is not associated with this notion of +extended membership test. Please don't think of these as sets, it will confuse +you. the extended membership notation + + if A in bla | ma | ga + +is just a short hand for + + if A ? bla or A ? ma or A ? ga + +where ? is = for a single value, and IN for a subtype or range, and note that +the = here is equality, NOT a call to the "=" operator (Steve Bairds point (*)) + +no sets are involved. + +I think it is this wrong thinking about sets that is causing your confusion. The +AI does talk about subsets of values, but it definitely does NOT introduce some +new semantic concept of a set. And in no sense does + + if A in bla + +talk about a singleton set, it is just shorthand for + + if A = bla + +Just as + + if A in bla | mah + +is shorthand for + + if A = bla or A = mah + +> I find this at odds with Ada, because this kind of overloading is new in Ada. +> This is not intuitive, and does not bring much, so I don't like it. + +There is no overloading in sight??? + +(*) Steve Baird's point in case you missed it is that + + A in B + +is not the same as + + A = B + +if = has been redefined. + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 4:44 PM + +Note that we did consider introducing a syntactic notion of sets pascal style, +something like + + (A, B, C .. D) + +but we decided against this, on the grounds that borrowing the case syntax was +neater. Note that we don't think of + + when A | B | C .. D => + +as introducing a set! + +**************************************************************** + +From: Dan Eilers +Date: Tuesday, March 29, 2011 5:01 PM + +> In fact, since operators are not by default directly visible, I +> suspect that with this change we will see some new idioms emerge, +> including: +> +> while Ptr not in null loop +> ... +> Ptr := Ptr.Next; +> end loop; +> +> avoiding the need for that pesky "use type Blah;" + +If in fact this is considered a useful idiom, it would be better as: + + while Ptr not null loop + +since the "in" adds nothing except confusion. + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 5:22 PM + +Well to me it adds no confusion, but I certainly dislike Dan's suggestion of +adding an entirely new construct for this purpose! + +Also, null is just an example here. + +**************************************************************** + +From: Dan Eilers +Date: Tuesday, March 29, 2011 5:22 PM + +> But there are no sets here, the word "set" is not associated with this +> notion of extended membership test. Please don't think of these as +> sets, it will confuse you. the extended membership notation + +As an implementor you see no sets. But users, particularly those familiar with +Pascal's sets, will see this as set membership, and as you agree, seeing these +as sets will confuse you. + +A future version of Ada might actually have first-class sets, which would likely +be even more confusing. + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 5:39 PM + +Well perhaps Pascal users will see it this way, but equally COBOL users will be +familiar with this simply as a short hand for extended tests + + IF TRANSACTION IS OPEN OR CLOSE OR TERMINATE THEN + .... + +no one thinks of this as a set in COBOL, and as I say, I don't think people +think of the WHEN construct as defining a set per se. + +If there are ever first class sets in Ada (I doubt this would ever happen), we +will have a general set constructor something like + + {x,y,z} + +as in SETL :-) + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 5:48 PM + +BTW it is really Steve Bairds three points that convince me we should leave the +status quo in place. At this stage I think there has to be a pretty strong +burden of proof to change this, and I don't see that case as having been made +convincingly. + +**************************************************************** + +From: Dan Eilers +Date: Tuesday, March 29, 2011 5:44 PM + +> IF TRANSACTION IS OPEN OR CLOSE OR TERMINATE THEN +> .... +> +> no one thinks of this as a set in COBOL, + +If Ada used "IS" instead of "IN" that would avoid the interpretation as set +membership in Ada as well. + +**************************************************************** + +From: Robert Dewar +Date: Tuesday, March 29, 2011 6:17 PM + +true, and of course these are called membership operations (although not set +membership operations, but I see how you could draw the conclusion. + +If we had + + if A in {B, C} then + +then the singleton would read more nicely + + if A in {B} then + +I still don't agree on balance with the recommendation to change this, we have +four reasons now to keep it as is, the three given by Steve, and the fourth +Tuck's idiom. + +Apart from that there is only a feeling of unease on the one hand from some +people, and on the other hand, others feel just fine about it, so on balance +that aesthetic balance does not seem to weigh heavily in either direction. + +There are a few ARG people who have not spoken, I am deactivating this thread +waiting for more people to chime in :-) + +**************************************************************** + +From: John Barnes +Date: Wednesday, March 30, 2011 3:39 AM + +We should leave it as it is. + +**************************************************************** + +From: Jean-Pierre Rosen +Date: Wednesday, March 30, 2011 9:41 AM + +> There are a few ARG people who have not spoken, I am deactivating this +> thread waiting for more people to chime in :-) + +Those who do not respond in general either a) don't care, b) don't understand +the issue, or c) are busy somewhere else. + +I used to be c), but I am moving to a). As everybody, I was first surprised, +then I understood the issue, and finally I think that this is a minimal issue +both ways. + +Given the current time frame, I cast my vote to leave it as is. + +**************************************************************** + +From: Brad Moore +Date: Friday, April 1, 2011 11:24 PM + +I'm also in the c) category, trying to get caught up with the ARG email. + +I have sympathy for Dan and Yannicks point of view but Steve's 3 arguments +are pretty convincing to me, and I feel they outweigh the benefits for making a +change. ****************************************************************

Questions? Ask the ACAA Technical Agent