* Equality operator overloading in ADA 83 @ 1997-04-21 0:00 Manuel Wenger 1997-04-22 0:00 ` Matthew Heaney ` (2 more replies) 0 siblings, 3 replies; 114+ messages in thread From: Manuel Wenger @ 1997-04-21 0:00 UTC (permalink / raw) Hi, I've started doing some DecADA 83 programming at a technical engineering school ... and I've run into a problem that I was unable to solve (and my teacher didn't know any better either :-)) I've tried to overload the "=" operator for fractions in a package. It obviously doesn't work if the type isn't defined as "limited private", and I don't want that. As an alternative, I found out that I might as well do a renaming declaration, just by defining the type as "private" - so I've tried doing that as well, and then using the following to rename the equal sign: function equal (n,m:fraction) return boolean; function "=" (n,n:fraction) return boolean renames equal; And what do I get? (I love VMS :-)) %ADAC-E-NOTEQOP, (1) Equal is not an equality operator [LRM 6.7(5)] Now - we've tried to look at manuals and everything, but we don't seem able to figure how to define an operator to be an "equality operator". We've just found some weird definitions like "A renaming declaration whose designator is the equality operator is only allowed to rename another equality operator. (For example, such a renaming declaration can be used when equality is visible by selection but not directly visible.)" (DEC Bookreader, ADA reference). In other words, how do I tell my "equal" function to be an equality operator, authorized to be renamed into "="? HELP! :) Please reply via e-mail Thanks in advance -Manuel (to reply, please remove the asterisk at the end of my address) ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-21 0:00 Equality operator overloading in ADA 83 Manuel Wenger @ 1997-04-22 0:00 ` Matthew Heaney 1997-04-22 0:00 ` Philip Brashear 1997-04-22 0:00 ` Mats Weber 1997-04-22 0:00 ` Kevin Cline 1997-04-22 0:00 ` Mats Weber 2 siblings, 2 replies; 114+ messages in thread From: Matthew Heaney @ 1997-04-22 0:00 UTC (permalink / raw) In article <01bc4e9b$ac0e7fa0$72041dc2@lightning>, "Manuel Wenger" <manuel@thunder.ch*> wrote: >I've tried to overload the "=" operator for fractions in a package. It >obviously doesn't work if the type isn't defined as "limited private", and >I don't want that. As an alternative, I found out that I might as well do a >renaming declaration, just by defining the type as "private" - so I've >tried doing that as well, and then using the following to rename the equal >sign: In Ada 83, you aren't allowed to override the predefined equality operator for nonlimited private types. A bit of a bummer, and that's why they changed it for Ada 95. Either you can make the type limited, and define the equality operator (and a Copy operation, too, while you're at it), or, add an Is_Equal operation and hope that clients remember to call that operation instead of "=". Or, if your type doesn't contain any access objects, you can leave the type as nonlimited private, and use the technique below to make sure predefined equality always works correctly. In Ada 95, you can replace the equality operator for nonlimited types. However, there is a caveat, necessited by backwards compatibility issues. The issue is that, if the type is not a tagged type, and if an object of the type is an component of a record or array, then the *predefined* operator - not the overridden one - is called. This is a real bummer. Note that if the type is tagged - even privately tagged - then the overidden version is always called. You can mitigate this issue 2 ways: 1. Always make sure equality works, irrespecitive of whether the predefined or overridden version is called. 2. Make the type privately tagged. Note that this is a server problem, not a client problem. You the implementor of an abstraction are responsible for satisfying the contract you advertised in the spec. A client should never have to worry that if he declares a record or array containing an object of your type, that equality won't work correctly. You the server must guarantee that equality always works. For types with value semantics, that is, containing no components that are access objects, then you can always make equality work, even predefined equality. You can do this with a bit of extra coding, or, just privately tagging the type. For types that have access object components, then you need to (privately) inherit from Controlled to prevent structure sharing, so you're tagged anyway, and the correct equality operator will get called. Consider a type such as Bounded_String: type Bounded_String is private; ... private type Bounded_String is record Buffer : String (1 .. Max_Length); Last : Natural := 0; end record; end; The simplest technique is to just privately tag the type: type Bounded_String is tagged record Buffer : String (1 .. Max_Length); Last : Natural := 0; end record; If you don't want to do that, then you have to make sure that every Buffer element has a known, default value. When you shorten the logical length of the Bounded_String, then you must assign the default value to the newly unused Buffer elements: Default_Character : constant Character := Ada.Latin_1.Nul; type Bounded_String is record Buffer : String (1 .. Max_Length) := (others => Default_Character); Last : Natural := 0; end record; For example, when you update a Bounded_String: procedure Set (Bounded : in out Bounded_String; To : String) is Last : Natural renames Bounded.Last; begin if To'Length >= Last then Bounded.Buffer (1 .. To'Length) := To; else declare Pad_Length : constant Positive := Last - To'Length; Pad : constant String (1 .. Pad_Length) := (others => Default_Character); begin Bounded.Buffer (1 .. Last) := To & Pad; end; end if; Last := To'Length; end Set; It took me a while to realize that, yes, even for types (without access objects) that have a physical length greater than the logical length, you can make the predefined equality work. This is true even for Ada 83, so you may be able to apply this technique to your problem. I would like to take this opportunity - while I'm on my soapbox :-) - to politely remind compiler vendors that they should make sure that equality for Ada.Strings.Bounded.Bounded_String always works. Either use some compiler magic to make sure the overridden equality operator gets called, privately tag Bounded_String, or implement the type using the technique I've shown above. You the purchaser of a compiler should test to make sure Bounded_String works. If the predefined equality is ever getting called, let your vendor know his product is broken. Perhaps this should be an ACVC test, too (maybe it is already). Matt -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Matthew Heaney @ 1997-04-22 0:00 ` Philip Brashear 1997-04-22 0:00 ` Mats Weber 1 sibling, 0 replies; 114+ messages in thread From: Philip Brashear @ 1997-04-22 0:00 UTC (permalink / raw) It appears that the original poster missed the significance of the term "equality operator". As the error message indicated, his "Equal" is not an equality operator. An equality operator is designated by the symbol "=". The "Equal" function might be an equality operatION, but it's not an equality operatOR. (The operatORs are all given by special symbols and names: "=", "<", ">", "<=", ">=", "/=", "not", "or", "and", "+", "-", etc. ) Phil Brashear Currently between jobs ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Matthew Heaney 1997-04-22 0:00 ` Philip Brashear @ 1997-04-22 0:00 ` Mats Weber 1997-04-22 0:00 ` Robert A Duff ` (2 more replies) 1 sibling, 3 replies; 114+ messages in thread From: Mats Weber @ 1997-04-22 0:00 UTC (permalink / raw) > It took me a while to realize that, yes, even for types (without access > objects) that have a physical length greater than the logical length, you > can make the predefined equality work. This is true even for Ada 83, so > you may be able to apply this technique to your problem. Yes, but the performance penalty is pretty big and it's hard to find the bug if you forget the padding just once. > I would like to take this opportunity - while I'm on my soapbox :-) - to > politely remind compiler vendors that they should make sure that equality > for Ada.Strings.Bounded.Bounded_String always works. Either use some > compiler magic to make sure the overridden equality operator gets called, > privately tag Bounded_String, or implement the type using the technique > I've shown above. The same holds for Ada.Strings.Unbounded, and there was some discussion on this a year ago or so here in c.l.a. Is anything being done so that an AI is issued to ensure this (if AIs still exist) ? > You the purchaser of a compiler should test to make sure Bounded_String > works. If the predefined equality is ever getting called, let your vendor > know his product is broken. Perhaps this should be an ACVC test, too > (maybe it is already). GNAT 3.09 would fail, I just chacked: there is no padding of strings shorter than the max length. Making Max_Length a discriminant of a subcomponent of Bounded_String would solve the problem, probably better (at least cleaner) than padding with nulls. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Mats Weber @ 1997-04-22 0:00 ` Robert A Duff 1997-04-22 0:00 ` Mats Weber 1997-04-22 0:00 ` Matthew Heaney 1997-04-22 0:00 ` Matthew Heaney 1997-04-24 0:00 ` Robert Dewar 2 siblings, 2 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-22 0:00 UTC (permalink / raw) In article <335CAEFE.35DC@elca-matrix.ch>, Mats Weber <Mats.Weber@elca-matrix.ch> wrote: >The same holds for Ada.Strings.Unbounded, and there was some discussion >on this a year ago or so here in c.l.a. Is anything being done so that >an AI is issued to ensure this (if AIs still exist) ? This is AI95-123, which has been approved by the ARG, but not (yet) by WG9. I've included it below. In general, I believe that ACVC tests do not get written based on AIs until WG9 has approved. In case anyone's interested, the AI's are stored on sw-eng.falls-church.va.us, in /public/adaic/standards/95com/ada-issues. - Bob !standard 04.05.02 (24) 97-03-19 AI95-00123/05 !class binding interpretation 96-07-23 !status ARG approved 10-0-2 (subject to editorial review) 96-10-07 !status work item (letter ballot was 6-6-0) 96-10-03 !status ARG approved 8-0-0 (subject to letter ballot) 96-06-17 !status work item 96-04-04 !status received 96-04-04 !priority High !difficulty Medium !subject Equality for Composite Types !summary 96-11-19 The primitive equality operators of language defined types compose properly, when the type is used as a component type, or a generic actual type. For any composite type, the order in which "=" is called for components is not defined by the language. Furthermore, if the result is determined before calling "=" on some components, the language does not define whether "=" is called on those components. !question 96-07-23 The following language-defined types are private, and have an explicitly defined primitive "=" operator: System.Address Ada.Strings.Maps.Character_Set Ada.Strings.Bounded.Generic_Bounded_Length.Bounded_String Ada.Strings.Unbounded.Unbounded_String Ada.Strings.Wide_Maps.Wide_Character_Set Ada.Task_Identification.Task_ID This would seem to imply that the composability of these "=" operators depends on whether the implementation chooses to implement them as tagged types, by 4.5.2(14-24): 14 For a type extension, predefined equality is defined in terms of the primitive (possibly user-defined) equals operator of the parent type and of any tagged components of the extension part, and predefined equality for any other components not inherited from the parent type. 15 For a private type, if its full type is tagged, predefined equality is defined in terms of the primitive equals operator of the full type; if the full type is untagged, predefined equality for the private type is that of its full type. ... 21 Given the above definition of matching components, the result of the predefined equals operator for composite types (other than for those composite types covered earlier) is defined as follows: 22 If there are no components, the result is defined to be True; 23 If there are unmatched components, the result is defined to be False; 24 Otherwise, the result is defined in terms of the primitive equals operator for any matching tagged components, and the predefined equals for any matching untagged components. This would cause portability problems. Also, in the above definition, what does "in terms of" mean? For a composite type, if some parts have an "=" with side effects, does the language define whether all of these side effects happen, and in what order? !recommendation 96-11-16 (See summary.) !wording 96-07-23 !discussion 97-03-19 Composability of equality means three things: 1. If a composite type has a component of type T with a user-defined equality operator, then the predefined equality of the composite type calls the user-defined equality operator of type T (for that component). 2. If an actual type T for a generic formal type has a user-defined equality operator, then the predefined equality on the generic formal type calls the user-defined equality operator of type T. 3. If a parent type T has a user-defined equality operator, then the predefined equality of a type extension of T calls the user-defined equality on T (for the parent part), in addition to comparing the extension parts. Non-composability means that the predefined equality is called for T, despite the fact that T has a user-defined equality operator. Of course, if there is no user-defined equality, then equality always composes properly. Number 3 is irrelevant here, since none of the types in question is (visibly) tagged. For a private type, if the underlying type is tagged, or if there is no user-defined equality, then equality composes. Otherwise, it does not. (Here, "underlying type" means the full type, or if that comes from a private type, then the underlying type of *that* type, and so on.) However, for the private types mentioned in the question, the RM does not specify whether the underlying type is tagged, nor whether the equality operator is truly user-defined (as opposed to just being the normal bit-wise equality). It is important that the composability of "=" for these types be defined by the language. We choose to make them composable. An implementation can achieve this by making the full type tagged. Alternatively, the implementation could simply use the predefined "=" for these types. (Alternatively, an implementation could treat these types specially, making them untagged, but with composable equality. However, this would add some complexity to the compiler.) Here is an analysis of implementation concerns for each type in question: - System.Address: The intent is for this type to directly represent a hardware address. Therefore, it is probably not feasible to to implement it as a tagged type. The simplest implementation of equality of Addresses is thus the normal bit-wise equality. This is what most users would expect, anyway. On certain segmented architectures, it is possible for two different addresses to point to the same location. The same thing can happen due to memory mapping, on many machines. Such addresses will typically compare unequal, despite the fact that they point to the same location. - Ada.Strings.Maps.Character_Set: A typical implementation will use an array of Booleans, so bit-wise equality will be used, so it will compose. - Ada.Strings.Bounded.Generic_Bounded_Length.Bounded_String: Two reasonable implementations are: (1) Nul-out the unused characters, and use bit-wise equality, and (2) use a tagged type with a user-defined equality. Either way, equality will compose. This is, admittedly, a slight implementation burden, because it rules out an untagged record with user-defined equality. - Ada.Strings.Unbounded.Unbounded_String: A tagged (controlled) type will normally be necessary anyway, for storage reclamation. In a garbage-collected implementation, a tagged type is not strictly necessary, but we choose to require composability anyway. - Ada.Strings.Wide_Maps.Wide_Character_Set: Some sort of data structure built out of access types is necessary anyway, so the extra overhead of composability is not a serious problem; the implementation can simply make the full type tagged. - Ada.Task_Identification.Task_ID: This will typically be a pointer-to-TCB of some sort (access-to-TCB, or index-into-table-of-TCB's). In any case, bit-wise equality will work, so equality will compose. As to the second question, the RM clearly does not define any order of calling "=" on components, nor does it say whether the results are combined with "and" or "and then". Equality operators with side effects are questionable in any case, so we allow implementations freedom to do what is most convenient and/or most efficient. Consider equality of a variant record: The implementation might first check that the discriminants are equal, and if not, skip the component-by-component comparison. Alternatively, the implementation might first compare the common elements, and *then* check the discriminants. A third possibility is to first compare some portions with a bit-wise equality, and then (conditionally) call user-defined equality operators on the other components. All of these implementations are valid. !appendix 97-03-19 ... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Robert A Duff @ 1997-04-22 0:00 ` Mats Weber 1997-04-22 0:00 ` Matthew Heaney 1 sibling, 0 replies; 114+ messages in thread From: Mats Weber @ 1997-04-22 0:00 UTC (permalink / raw) > - Ada.Strings.Bounded.Generic_Bounded_Length.Bounded_String: Two > reasonable implementations are: (1) Nul-out the unused > characters, and use bit-wise equality, and (2) use a tagged type > with a user-defined equality. Either way, equality will compose. > This is, admittedly, a slight implementation burden, because it > rules out an untagged record with user-defined equality. I think there is a third possibility that solves the "=" problem (predefined equality works just fine so that it does not need redeclaration): subtype Index is Natural range 0 .. Max_Length; type Bounded_String_Aux (Length : Index := 0) is record Value : String(1 .. Length); end record; type Bounded_String is record Value : Bounded_String_Aux; end record; (I don't know if two types are still necessary in Ada 95, i.e. can a full type declaration have discriminants with defaults if the visible type has none). We're lucky that all these operators have (Left, Right) as their parameter names, or we would have had another funny problem. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Robert A Duff 1997-04-22 0:00 ` Mats Weber @ 1997-04-22 0:00 ` Matthew Heaney 1997-04-23 0:00 ` Mats Weber 1997-04-24 0:00 ` Robert Dewar 1 sibling, 2 replies; 114+ messages in thread From: Matthew Heaney @ 1997-04-22 0:00 UTC (permalink / raw) In article <E91zFw.KDE@world.std.com>, bobduff@world.std.com (Robert A Duff) wrote: >It is important that the composability of "=" for these types be defined >by the language. We choose to make them composable. Ah, the voice of reason in a chaotic world. The right choice, of course. Thank you, thank you, thank you! Composability should always be guaranteed by user-defined types, too. Matt -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Matthew Heaney @ 1997-04-23 0:00 ` Mats Weber 1997-04-23 0:00 ` Robert Dewar 1997-04-23 0:00 ` Robert A Duff 1997-04-24 0:00 ` Robert Dewar 1 sibling, 2 replies; 114+ messages in thread From: Mats Weber @ 1997-04-23 0:00 UTC (permalink / raw) > Composability should always be guaranteed by user-defined types, too. There seems to be much disagreement on this question for all kinds of reasons. But I agree with you 100%. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-23 0:00 ` Mats Weber @ 1997-04-23 0:00 ` Robert Dewar 1997-04-24 0:00 ` Robert A Duff 1997-04-29 0:00 ` Mats Weber 1997-04-23 0:00 ` Robert A Duff 1 sibling, 2 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-23 0:00 UTC (permalink / raw) Mats Weber said <<> Composability should always be guaranteed by user-defined types, too. There seems to be much disagreement on this question for all kinds of reasons. But I agree with you 100%.>> It is helpful if you make clear whether you are making a pronouncement about the original Ada 83 design or the decision not to introduce upwards incompatibilities in the Ada 95 redesign (I trust you are NOT making a statement about Ada 95 implementations :-) ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-23 0:00 ` Robert Dewar @ 1997-04-24 0:00 ` Robert A Duff 1997-04-29 0:00 ` Mats Weber 1 sibling, 0 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-24 0:00 UTC (permalink / raw) In article <dewar.861851658@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: >It is helpful if you make clear whether you are making a pronouncement about >the original Ada 83 design or the decision not to introduce upwards >incompatibilities in the Ada 95 redesign (I trust you are NOT making a >statement about Ada 95 implementations :-) It would also be helpful to know whether you are talking about just equality, or all operators, or just composite types, or what. (E.g., should redefining "<" on T cause array-of-T's "<" to change?) It's not easy to know where to draw the line. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-23 0:00 ` Robert Dewar 1997-04-24 0:00 ` Robert A Duff @ 1997-04-29 0:00 ` Mats Weber 1997-05-01 0:00 ` Robert Dewar 1 sibling, 1 reply; 114+ messages in thread From: Mats Weber @ 1997-04-29 0:00 UTC (permalink / raw) Robert Dewar wrote: > > Mats Weber said > > <<> Composability should always be guaranteed by user-defined types, too. > > There seems to be much disagreement on this question for all kinds of > reasons. But I agree with you 100%.>> > > It is helpful if you make clear whether you are making a pronouncement about > the original Ada 83 design or the decision not to introduce upwards > incompatibilities in the Ada 95 redesign (I trust you are NOT making a > statement about Ada 95 implementations :-) My pronouncement is about Ada 95; Ada 83 was "clean" with respect to equality because of the strict rules on its redefinition (if we don't count the unexpected possibility of redefining it for non-limited types) and the fact that it does not automatically compose when some component is of a limited type. My view is that if you allow redefinition of "=", then you must make sure it behaves (composes, does not reemerge) correctly, which was not done in Ada 95 except for tagged types. I also think that the upward incompatibilities that the non-reemergence of predefined operations would have introduced are minimal compared to how a programmer is betrayed when he writes type T is private; function "=" (L, R : T) return Boolean; and the predefined "=" reemerges in some places with an unknown effect since the type is private. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-29 0:00 ` Mats Weber @ 1997-05-01 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-05-01 0:00 UTC (permalink / raw) Mats said <<My pronouncement is about Ada 95; Ada 83 was "clean" with respect to equality because of the strict rules on its redefinition (if we don't count the unexpected possibility of redefining it for non-limited types) and the fact that it does not automatically compose when some component is of a limited type.>> Well I don't agree with your definition of clean at all, but from your point of view, isn't the above a bit like saying, "this room is clean except for the two heaps of rubbish in the middle of the floor". The mechanism for redefinition of equality in Ada 83 is well defined. The fact that someone did not expect it has no influence on the language standard -- and more to the point, this mechanism is very widely used in Ada 83 programs. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-23 0:00 ` Mats Weber 1997-04-23 0:00 ` Robert Dewar @ 1997-04-23 0:00 ` Robert A Duff 1997-04-24 0:00 ` Mats Weber 1 sibling, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-04-23 0:00 UTC (permalink / raw) In article <335E0B1F.12C9@elca-matrix.ch>, Mats Weber <Mats.Weber@elca-matrix.ch> wrote: >> Composability should always be guaranteed by user-defined types, too. > >There seems to be much disagreement on this question for all kinds of >reasons. But I agree with you 100%. I think I agree that "=" should compose, in the sense that composite types call the user-defined "=" of their components, and the predefined "=" doesn't "re-emerge" in generics. But how far do you think we should carry this? E.g. if "=" is redefined for a scalar type, does that affect case statements on that type? After all, case stms check the case expression for equality with some values. What about operators other than "="? If "/" is redefined for an integer type, should Text_IO.Integer_IO know about it? It might well make Put(some-integer) do the "wrong" thing, since the generic might need to divide by 10. If I redefine "<" on a scalar type, should "<" on an array-of-that-type call it? - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-23 0:00 ` Robert A Duff @ 1997-04-24 0:00 ` Mats Weber 1997-04-24 0:00 ` Matthew Heaney ` (3 more replies) 0 siblings, 4 replies; 114+ messages in thread From: Mats Weber @ 1997-04-24 0:00 UTC (permalink / raw) Robert A Duff wrote: > I think I agree that "=" should compose, in the sense that composite > types call the user-defined "=" of their components, and the predefined > "=" doesn't "re-emerge" in generics. But how far do you think we should > carry this? E.g. if "=" is redefined for a scalar type, does that > affect case statements on that type? After all, case stms check the > case expression for equality with some values. What about operators > other than "="? If "/" is redefined for an integer type, should > Text_IO.Integer_IO know about it? It might well make Put(some-integer) > do the "wrong" thing, since the generic might need to divide by 10. Yes, I would affect case statements, and also allow case for types other than discrete types, such as strings, defining them as equivalent to an if elsif sequence, with the selector expression being evaluated only once. One can still keep the advantage of having to cover all possible values when the selector's subtype is static and discrete with no "=" redefinition. Otherwise, there would be a when others => null by default as the last choice. For instances of predefined packages such as Text_IO.Integer_IO with types whose arithmetic has been messed with, I think it's OK if they don't work correctly. It's easy to make the few needed type conversions to make sure IO works with such types, which require special care anyway. I think that the argument of backward compatibility with Ada 83 is not that important (just my opinion). I think that if someone redefines an operator for a type, then he probably has a good reason to do so, and that operator becomes part of the abstraction provided by that type and must stick with it wherever the types goes, with no exception. > If I redefine "<" on a scalar type, should "<" on an array-of-that-type > call it? Yes. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Mats Weber @ 1997-04-24 0:00 ` Matthew Heaney 1997-04-25 0:00 ` Robert Dewar 1997-04-25 0:00 ` Robert Dewar 1997-04-24 0:00 ` Robert A Duff ` (2 subsequent siblings) 3 siblings, 2 replies; 114+ messages in thread From: Matthew Heaney @ 1997-04-24 0:00 UTC (permalink / raw) In article <335F5971.6375@elca-matrix.ch>, Mats.Weber@elca-matrix.ch wrote: >I think that the argument of backward compatibility with Ada 83 is not >that important (just my opinion). I think that if someone redefines an >operator for a type, then he probably has a good reason to do so, and >that operator becomes part of the abstraction provided by that type and >must stick with it wherever the types goes, with no exception. And this time I agree with you 100%. With respect to redefining equality, if introducing a backwards incompatibility was the price for always having the overriding version get called, then so be it. Alas, I wasn't on the design commitee, and they made a different choice. Oh, well. They're smart guys, and they had their reasons. To remember that predefined equality re-emerges when a bounded_string is a record or array componant is to a lot (too much, I say) to ask the average programmer. Most programmers don't know that predefined operators even in Ada 83 re-emerge for a type passed as a generic actual, so what magic is supposed to happen to make them aware of the re-emergence of predefined equality in Ada 95? This whole issue of re-emergence of operators is something I really wish no Ada programmer ever had to think about, and it will only contribute to the perception (reality?) of Ada as a "complex language." My Prognistication is that this will be a pernicious source of error in Ada 95 systems. At a minimum we should guarantee that predefined types - such as Ada.Strings.Bounded.Bounded_String - are composable. Because it would be very naive to think that a tired programmer who has been furiously working all weekend, and is still hacking away at 11:30 Sunday night because he has a code delivery Monday morning, is going to be even remotely thinking about when predefined equality re-emerges. So let's solve his problem so that he _never_does_ have to think about it, by guaranteeing that Bounded_String is composable. The whole point of a high level language is so that the programmer _doesn't_ have to think about those things. He should be thinking about the problem, not the solution. We have to remove programming language as a barrior to the production of correct software systems. Gee, I think I'm beginning to sound like someone else. Bertrand, are you listening? Matt -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Matthew Heaney @ 1997-04-25 0:00 ` Robert Dewar 1997-04-25 0:00 ` Matthew Heaney 1997-04-26 0:00 ` Fergus Henderson 1997-04-25 0:00 ` Robert Dewar 1 sibling, 2 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-25 0:00 UTC (permalink / raw) Matthew said <<Alas, I wasn't on the design commitee, and they made a different choice. Oh, well. They're smart guys, and they had their reasons.>> Right, it is usually the case that if you do not see the argument on the other side, it is because you don't know what it is! Language design is seldom simple. Actually the way I look at it, the troublesome cases are all with discrete types, and I wonder whether the better scheme might not have been to disallow the redefinition of equality on discrete types, or at least restrict it. In the case of composite types, or access types, it seems like there are really no problems in allowing composition -- maybe that says tha the COmpose_Equality pragma that I suggested should apply only to composite types and access types, though on the other hand it is harmless for discrete types. One of the problems arises in the treatment of private types. I often find it a problem that I want to redefine operators in the public view for those who see only the private type, but in the body it is a nuisance to have these operators around anyway. For examle, if the full declaration of Address is a modular type, which is reasonable, then you get ambiguities in the body of children of system that use Storage_Elements, which is a pain. What I would really like is the ability to declare operators for the client who sees the private view and not have these visible to the body. If you had some such arrangement, then it would be completely harmless to allow equality to compose for a public operator of this type (since in the body, the equality operator would not be visible, so these embarrassing questions about case statements, generics etc, would not arise. Note that if you have shared generics, there is a real cost to having equality compose. It means you have to thunk equality operators for all types, which is really painful from an efficiency point of view -- that is another factor in the original decision, but it too applies only to discrete types (you would have to thunk the equality operators for other kinds of types, but at least for composites, this would be harmless). I guess the generic case also makes one requestion the statement above about access types -- these don't cause problems with implicit equalities, e.g. in case, but they do cause efficiency embarrassments in shared generics. A lot of the design is driven by wanting to preserve the possibility for shared generics. My taste and, I believe, Tuck's taste is to decide once and for all that generics are not shared, and design the lanuage accordingly, but two existing vendors (RR particularly) use shared generics extensively, and Randy Burkhardt (from RR) was always reminding us about shared generics, and the need for accomodaing them. My feeling is that trying to design the language so eithre shared generics or macro-inserted generics work is a mistake. The two styles of implementations may be semantically equivalent, but they have a huge effect on portability in practice. You code in a completely different way if you have shared generics, since there is no reason not to write giant generics, whereas if you don't have shared generics, then you factor out the generic parts. Actually it is not entirely semantially neutral, there is a problem with exceptions, in that in the shared model there is only one, and in the unshared case there are multiple exceptions -- the current Ada 95 solution in this area is not very appetizing, and also causes portability difficulties. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Robert Dewar @ 1997-04-25 0:00 ` Matthew Heaney 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Fergus Henderson 1 sibling, 1 reply; 114+ messages in thread From: Matthew Heaney @ 1997-04-25 0:00 UTC (permalink / raw) In article <dewar.861970700@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: >One of the problems arises in the treatment of private types. I often find >it a problem that I want to redefine operators in the public view for those >who see only the private type, but in the body it is a nuisance to have these >operators around anyway. Yes, I agree. This would be a very nice feature to have. You can always resort to derivation, though, so that you can view the "predefined" version of the type. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Matthew Heaney @ 1997-04-26 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) <<You can always resort to derivation, though, so that you can view the "predefined" version of the type.>> How does that help, then you have to use conversions all over the place, but typically in the situations where there is a problem: x := x + 1; where x is type address, you only need a qualiffication in any case to resolve it, as in x := x + Offset'(1); but it is annoying to have to put these conversoins or qualifications in, that's the problem! ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Robert Dewar 1997-04-25 0:00 ` Matthew Heaney @ 1997-04-26 0:00 ` Fergus Henderson 1997-04-26 0:00 ` Robert A Duff 1997-04-27 0:00 ` Robert Dewar 1 sibling, 2 replies; 114+ messages in thread From: Fergus Henderson @ 1997-04-26 0:00 UTC (permalink / raw) dewar@merv.cs.nyu.edu (Robert Dewar) writes: >Actually it is not entirely semantially neutral, there is a problem with >exceptions, in that in the shared model there is only one, and in the >unshared case there are multiple exceptions -- the current Ada 95 solution >in this area is not very appetizing, and also causes portability difficulties. What do you mean when you say there are multiple exceptions in the unshared case? Could someone please elaborate, and/or give a pointer to the appropriate part of the RM? -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit" PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Fergus Henderson @ 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-27 0:00 ` Robert Dewar 1 sibling, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-04-26 0:00 UTC (permalink / raw) In article <5jsfdm$e50@mulga.cs.mu.OZ.AU>, Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> wrote: > >dewar@merv.cs.nyu.edu (Robert Dewar) writes: > >>Actually it is not entirely semantially neutral, there is a problem with >>exceptions, in that in the shared model there is only one, and in the >>unshared case there are multiple exceptions -- the current Ada 95 solution >>in this area is not very appetizing, and also causes portability difficulties. Robert, unless I'm confused about what you're talking about, I think you're remembering an earlier version of Ada 9X. Ada 95 is the same as Ada 83 in this regard. In Ada 83, if you declare an exception in a generic, then each instance of that generic has its own copy of that exception. This follows from the fact that generic instantiation is defined as a textual copy, with some exceptions (the main exception being that name resolution is not "redone" on the instance). There was a version of Ada 9X that proposed to change this rule, by saying it is OK if the compiler wants to view them all as the same exception. This would simplify code-sharing. However, this language change was rejected by reviewers, primarily on the basis of upward compatibility concerns. I believe this proposed change was restricted to exceptions declared in the generic body, and it's not easy to write a test case that can tell the difference, so I'm not sure those upward compatibility concerns were sensible. So Ada 95 retains the Ada 83 rule. If you share code for instances, you have to make it look like each exception has its own identity. >What do you mean when you say there are multiple exceptions in the unshared >case? Could someone please elaborate, and/or give a pointer to the >appropriate part of the RM? - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert A Duff @ 1997-04-26 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) Robert Duff said <<Robert, unless I'm confused about what you're talking about, I think you're remembering an earlier version of Ada 9X. Ada 95 is the same as Ada 83 in this regard. In Ada 83, if you declare an exception in a generic, then each instance of that generic has its own copy of that exception. This follows from the fact that generic instantiation is defined as a textual copy, with some exceptions (the main exception being that name resolution is not "redone" on the instance).>> Oops yes, sorry, I was indeed remembering the earlier version. So in fact we still have complete semantic consistency between the code sharing and macro instantiations -- boy that rule about separate exceptions must be a real pain for the generic code sharing guys :-) ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Fergus Henderson 1997-04-26 0:00 ` Robert A Duff @ 1997-04-27 0:00 ` Robert Dewar 1 sibling, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-27 0:00 UTC (permalink / raw) Fergus said <<What do you mean when you say there are multiple exceptions in the unshared case? Could someone please elaborate, and/or give a pointer to the appropriate part of the RM?>> As Bob Duff pointed out, not only are there multiple exceptions in the unshared case, but also in the shared case, i.e. if an exception is declared in a generic template, then independent of whether or not generics are shared, there is a disctinct exception in each instance. It is possible (though a bit tricky) to write a program that can detect this. What this means for shared generics is that, unlike the situation elsewhere, you do not know the identify of exceptions statically at compile time, which is a pain for building static exception tables. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Matthew Heaney 1997-04-25 0:00 ` Robert Dewar @ 1997-04-25 0:00 ` Robert Dewar 1997-04-25 0:00 ` Matthew Heaney 1 sibling, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-25 0:00 UTC (permalink / raw) Matthew says <<The whole point of a high level language is so that the programmer _doesn't_ have to think about those things. He should be thinking about the problem, not the solution. We have to remove programming language as a barrior to the production of correct software systems. Gee, I think I'm beginning to sound like someone else. Bertrand, are you listening?>> But that's motherhood and apple pie. Everyone believes that! Whenever you see a feature you don't like, you can be sure that it was designed that way with the above principle in mind, and perhaps the above principle is the driving one. For example, it seems clearly to violate this principle to compose equality for scalar types, and then not use this composed equality in case statements. Whenever you thnk that a general and obvious, and universally acceptable principle such as the above one clearly argues for one side in a controversial issue, you are probably missing some subtleties! ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Robert Dewar @ 1997-04-25 0:00 ` Matthew Heaney 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 0 siblings, 2 replies; 114+ messages in thread From: Matthew Heaney @ 1997-04-25 0:00 UTC (permalink / raw) In article <dewar.861971395@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: >Whenever you thnk that a general and obvious, and universally acceptable >principle such as the above one clearly argues for one side in a >controversial issue, you are probably missing some subtleties! Fair enough, but let me ask you this. If you didn't have backwards compatibility as a goal, then would you have made it the rule that types compose whose equality operator had been redefined? -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Matthew Heaney @ 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1 sibling, 0 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-26 0:00 UTC (permalink / raw) In article <mheaney-ya023680002504972002170001@news.ni.net>, Matthew Heaney <mheaney@ni.net> wrote: >Fair enough, but let me ask you this. If you didn't have backwards >compatibility as a goal, then would you have made it the rule that types >compose whose equality operator had been redefined? Well, compatibility wasn't much of an issue specifically for "=", because it wasn't allowed for non-lim types in Ada 83. But if "=" composes, then one asks oneself whether "<" composes, and so on, and *those* questions do raise backward compatibility issues. In retrospect, I admit that I probably would go further, at least for "=", in terms of composability. But I'm not exactly sure where to draw the line. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Matthew Heaney 1997-04-26 0:00 ` Robert A Duff @ 1997-04-26 0:00 ` Robert Dewar 1 sibling, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) Matthew Heaney said <<Fair enough, but let me ask you this. If you didn't have backwards compatibility as a goal, then would you have made it the rule that types compose whose equality operator had been redefined?>> I don't know -- depends whether we could have come up with a satisfactory solution to the problems which lead to the decision in the first place. We did not look hard, because of the compatibility issues. Bu there are troublesome problems here ... see previous posts for hints ... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Mats Weber 1997-04-24 0:00 ` Matthew Heaney @ 1997-04-24 0:00 ` Robert A Duff 1997-04-24 0:00 ` Robert Dewar ` (3 more replies) 1997-04-28 0:00 ` Robert Dewar 1997-04-28 0:00 ` Robert Dewar 3 siblings, 4 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-24 0:00 UTC (permalink / raw) In article <335F5971.6375@elca-matrix.ch>, Mats Weber <Mats.Weber@elca-matrix.ch> wrote: >Yes, I would affect case statements, So, you mean: type T is range -10**9..10**9; function "="(X, Y: T) return Boolean; -- I hate "Left" and "Right". X: T; subtype Negative is T range T'First..-1; subtype Positive is T range 1..T'Last; case X is when Negative => Do_This; when 0 => Do_That; when Positive => Do_The_Other_Thing; end case; This should compare a billion numbers for equality with X, using the user's "=" operator? Hmm. Perhaps a reasonable thing for a new language, but rather out of the question for a "language revision" like Ada 9X. Of course, if one could redefine "in".... >...and also allow case for types other >than discrete types, such as strings, defining them as equivalent to an >if elsif sequence, with the selector expression being evaluated only >once. I would also like to see case statements on strings, but that's a much higher level language than Ada, I think. >One can still keep the advantage of having to cover all possible values >when the selector's subtype is static and discrete with no "=" >redefinition. Otherwise, there would be a when others => null by default >as the last choice. Bad choice. Better to make it a run-time error. >For instances of predefined packages such as Text_IO.Integer_IO with >types whose arithmetic has been messed with, I think it's OK if they >don't work correctly. It's easy to make the few needed type conversions >to make sure IO works with such types, which require special care >anyway. I might agree, except that I haven't the foggiest notion of how one specifies this precisely. I mean, the RM doesn't *say* Text_IO.Integer_IO needs to do a "/" by 10. I just happen to know that the implementation *might*. So what should the *spec* of Text_IO say about types that have redefined "/"? Or "mod" or "rem" or "-" etc.? >I think that the argument of backward compatibility with Ada 83 is not >that important (just my opinion). Indeed (just your opinion). In the Ada 9X project, it was an overriding concern. >... I think that if someone redefines an >operator for a type, then he probably has a good reason to do so, and >that operator becomes part of the abstraction provided by that type and >must stick with it wherever the types goes, with no exception. The problem is that you don't know where it goes -- for example, suppose there's a Sort generic. You don't know if it's defined in terms of "<=" or ">=" -- and it doesn't matter, so long as nobody redefines one without redefining the other. >> If I redefine "<" on a scalar type, should "<" on an array-of-that-type >> call it? > >Yes. OK, but then if I redefine "<" on a scalar type, should ">=" change? After all, ">=" is (or could be) defined as "not <". Historical note: I believe the Red language tried to make sure overloadings of the comparison ops "made sense" in this way -- you could overload two of them, and the other four would automatically change. - Bob P.S. I have a lot of sympathy for your point of view. I'm just griping because it's hard to fit in to Ada. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Robert A Duff @ 1997-04-24 0:00 ` Robert Dewar 1997-04-25 0:00 ` Robert A Duff 1997-04-25 0:00 ` Kevin Cline ` (2 subsequent siblings) 3 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-24 0:00 UTC (permalink / raw) Robert Duff says <<I would also like to see case statements on strings, but that's a much higher level language than Ada, I think.>> I don't see what you mean. The semantic esssence of a case statement is that there is a finite set of possibilities which must b covered. Otherwise it is mere syntactic sugar for elsif ... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Robert Dewar @ 1997-04-25 0:00 ` Robert A Duff 1997-04-26 0:00 ` Nick Roberts 1997-04-27 0:00 ` Robert Dewar 0 siblings, 2 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-25 0:00 UTC (permalink / raw) In article <dewar.861930356@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: >I don't see what you mean. The semantic esssence of a case statement is >that there is a finite set of possibilities which must b covered. Otherwise >it is mere syntactic sugar for elsif ... Why finite? The "essence" is that you have a bunch of mutually exclusive possibilities, and that you cover all the cases, as in: case To_Lower(X) is -- Not Ada! when "begin" => Do_This; when "end" => Do_That; when others => Do_The_Other; end case; Ada's choice is to check those rules at compile time, but that's not part of the "essence". It's a reasonable choice, though. Of course, I've written "when others => raise ...;" sometimes. But either way, it doesn't require forbidding strings and other types. That decision is based on ease-of-implementation and ease-of-efficient-implementation, I think. I'm not arguing that Ada should have this feature -- it's a useful feature, but doesn't really match the semantic level of Ada. (When you start having super-high-level features, you can no longer guess how efficient the implementation will be. E.g. if there are a lot of branches, will the compiler generate a hash table of some sort? A perfect has function? Who knows?) The above is clearer than: if To_Lower(X) = "begin" then Do_This; elsif To_Lower(X) = "end" then Do_That; else Do_The_Other; end if; for two reasons: you know the case expression is evaluated exactly once, so you needn't worry about side effects, and you know that exactly one of the case alternatives applies, whereas with an "elsif" chain, it might be the case that two of the alternatives are True, but the programmer carefully ordered them so that you never get to the second one. In other words, you know these useful facts when you see "case", whereas with "elsif" chains, you need to study the code carefully to know these facts, if they are true in a particular case (or rely on comments, which might lie, or might not be there). - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Robert A Duff @ 1997-04-26 0:00 ` Nick Roberts 1997-04-26 0:00 ` Robert A Duff ` (2 more replies) 1997-04-27 0:00 ` Robert Dewar 1 sibling, 3 replies; 114+ messages in thread From: Nick Roberts @ 1997-04-26 0:00 UTC (permalink / raw) Robert A Duff <bobduff@world.std.com> wrote in article <E973qr.89t@world.std.com>... [case example] > Ada's choice is to check those rules at compile time, but that's not > part of the "essence". [...] either way, it > doesn't require forbidding strings and other types. That decision is > based on ease-of-implementation and ease-of-efficient-implementation, I > think. I'm not arguing that Ada should have this feature -- it's a > useful feature, but doesn't really match the semantic level of Ada. > (When you start having super-high-level features, you can no longer > guess how efficient the implementation will be. E.g. if there are a lot > of branches, will the compiler generate a hash table of some sort? A > perfect has function? Who knows?) > The [case example] is clearer than: [an elsif sequence] > for two reasons: you know the case expression is evaluated exactly once, > so you needn't worry about side effects, and you know that exactly one > of the case alternatives applies, whereas with an "elsif" chain, it > might be the case that two of the alternatives are True, but the > programmer carefully ordered them so that you never get to the second > one. In other words, you know these useful facts when you see "case", > whereas with "elsif" chains, you need to study the code carefully to > know these facts, if they are true in a particular case (or rely on > comments, which might lie, or might not be there). The Ada language makes no specifications for the efficiency of the implementation of any construct anyway. Most programmers would be aware that a case statement applied to a non-discrete type would (probably) have to be implemented as a sequence of comparisons. As to the property of mutual exclusion - this is the 'essence' of the case statement - the implementation would probably have to test every choice at run time in order to check that only one choice evaluates to True (and raise an exception otherwise). In all other respects, I cannot see any reason why the suggested extension to the case statement would be impracticable. It would surely be a boon to programmers, as it would be a neat way express the mutual exclusion implied in certain situations, and, at the same time, have a runtime check (which could perhaps be removed by a pragma Suppress where necessary) to enforce this exclusion. Programmers would have to be taught not to use the facility inappropriately (as with many other Ada features). Maybe in a future revision. Nick. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Nick Roberts @ 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Robert Dewar 1997-04-29 0:00 ` Mats Weber 2 siblings, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-04-26 0:00 UTC (permalink / raw) In article <01bc5244$315f1560$28f982c1@xhv46.dial.pipex.com>, Nick Roberts <Nick.Roberts@dial.pipex.com> wrote: >The Ada language makes no specifications for the efficiency of the >implementation of any construct anyway. True. I don't know of any programming language that does. It's too hard, especially with modern hardware that confuses things with all kinds of caching and whatnot. However, in a language at the level of Ada, you can usually guess roughly how efficient a given operation will be. For example, I can be pretty sure that arrays are laid out as contiguous storage in memory, and so indexing is implemented as a constant-time algorithm. In a higher-level language that has associative arrays, it's harder to guess about the efficiency of array indexing. I must admit that case statements are not quite so easy to guess about. Surely any decent compiler will use a jump table when appropriate, but if the choices are sparse, a compiler could do a binary search of an ordered table, or an elsif sequence, for example. One other exception to my claim above is generics -- sharing vs. not sharing vs. sometimes sharing is enough of an efficiency issue that it strongly affects the sort of code you write. But I still think that for *most* features of Ada, you can make a pretty good guess about efficiency based on the source code, despite the fact that the RM doesn't say anything about it. (E.g. I expect an assignment of integers to normally take about 1 instruction or so.) >... Most programmers would be aware >that a case statement applied to a non-discrete type would (probably) have >to be implemented as a sequence of comparisons. You mean a series of "if .. elsif .. elsif..."? That's certainly not the best approach, in general. For testing large numbers of strings, you might want some sort of table lookup (binary search, hash table, or whatever). The general style of Ada is to allow the *programmer* to make that choice. >As to the property of mutual exclusion - this is the 'essence' of the case >statement Yes. Mutual exclusion and no duplicates. So the reader need not worry about the order in which the choices appear (which is necessary for elsif sequences). >... - the implementation would probably have to test every choice at >run time in order to check that only one choice evaluates to True (and >raise an exception otherwise). You're mixing two things here. The suggestion was to allow composite types in case statements. In addition, you could (1) retain the rule that the choices have to be static, and change the rules of static expressions so that more things are static (e.g. a constant initialized to a record aggregate containing all compile-time-known stuff), or (2) do as you say here, and do a run-time check. Extending case statements to composite types doesn't *require* number (2), and my example used only static string expressions as choices. (1) vs. (2) is the usual trade-off about compile-time vs. run-time checks -- the former gives you error messages earlier, which is good, but reduces flexibility. Note that number (2) could involve some very slow checks, which is again not the style of Ada. If I were adding this feature to Ada, I would probably go with number (1). >... In all other respects, I cannot see any >reason why the suggested extension to the case statement would be >impracticable. It would surely be a boon to programmers, as it would be a >neat way express the mutual exclusion implied in certain situations, and, >at the same time, have a runtime check (which could perhaps be removed by a >pragma Suppress where necessary) to enforce this exclusion. Programmers >would have to be taught not to use the facility inappropriately (as with >many other Ada features). > >Maybe in a future revision. I doubt it. This is the sort of feature you might find in a language like perl or SETL, but Ada is too low-level for this sort of feature, IMHO. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert A Duff @ 1997-04-26 0:00 ` Robert Dewar 1997-04-27 0:00 ` Robert A Duff 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) Bob Duff said <<You mean a series of "if .. elsif .. elsif..."? That's certainly not the best approach, in general. For testing large numbers of strings, you might want some sort of table lookup (binary search, hash table, or whatever). The general style of Ada is to allow the *programmer* to make that choice.>> What makes you thnk a compiler cannot as easily do this kind of optimization for a series of comparisons against constant strings as it could for a possibly extededn version of the case statement. Personally I doubt this optimization is worth while in either case, but it is just as easy to do it in the if .. elsif .. elsif ... case if all comparison values are static expressions (which allows you to detect duplicates -- and hopefully give warnings when you detect them!) ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar @ 1997-04-27 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-04-27 0:00 UTC (permalink / raw) In article <dewar.862088714@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: >What makes you thnk a compiler cannot as easily do this kind of optimization >for a series of comparisons against constant strings as it could for a >possibly extededn version of the case statement. Sure, an Ada compiler could do that. But none does (that I know of). That's not because it's infeasible. I think it has more to do with expectations. Nobody would expect that optimization, so nobody does it. And programmers who want to compare strings build hash tables, or whatever other technique they think is appropriate, by hand. They don't *expect* the compiler to do it for them. With a case statement, expectations are different. I certainly expect a jump table, when appropriate, rather than a series of compares. If case statements allowed strings, but still required static choices, I'm not sure what to expect -- but a series of elsifs certainly isn't the only reasonable choice. That was my point: when you have very high-level language features, you tend to lose the ability to guess what your compiler implementer is going to do, in terms of efficiency. Consider SETL, which has all kinds of fancy ways of implementing sets, versus Pascal, where the built-in set type is *expected* to be implemented as a bit string (although such things can never be *required*). - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-27 0:00 ` Robert A Duff @ 1997-04-26 0:00 ` Robert Dewar 1997-04-28 0:00 ` Simon Wright 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) i<<Sure, an Ada compiler could do that. But none does (that I know of). That's not because it's infeasible. I think it has more to do with expectations. Nobody would expect that optimization, so nobody does it. And programmers who want to compare strings build hash tables, or whatever other technique they think is appropriate, by hand. They don't *expect* the compiler to do it for them. With a case statement, expectations are different. I certainly expect a jump table, when appropriate, rather than a series of compares. If case statements allowed strings, but still required static choices, I'm not sure what to expect -- but a series of elsifs certainly isn't the only reasonable choice.>> Typically a compiler would just transform the two structures into something common anyway, so I really don't see this. Since you mention Setl, it does indeed have general case statements, but no attempt is made to optimize the fancy ones. Yes, we all expect a jump table for the discrete case, but as you say, there are no built in expectations for the string case. The reason that no Ada compiler does that optimization for elsif's is not because it is hard, it is because it is not worth doing -- and I don't think optimizing the case would be any more worth while, it is simply too unusual an idiom (a case against a large number of strings that are staticaly known at compile time) to be worthwhile. I have trouble thinking of any reasonable examples ... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar @ 1997-04-28 0:00 ` Simon Wright 1997-04-29 0:00 ` Robert I. Eachus 0 siblings, 1 reply; 114+ messages in thread From: Simon Wright @ 1997-04-28 0:00 UTC (permalink / raw) dewar@merv.cs.nyu.edu (Robert Dewar) writes: > it is simply > too unusual an idiom (a case against a large number of strings that are > staticaly known at compile time) to be worthwhile. I have trouble thinking > of any reasonable examples ... > In a way this happens in the Xt (Motif) arrangement for resource names: the effect is somewhat like having an associative array. I guess if that was the requirement, and the index names were predetermined, you might want to do it using a case ... I don't suppose Xt is very clever here, there is some optimisation to allow the use of predeclared instances of the strings so that an address comparison can be used instead of strcmp(). ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-28 0:00 ` Simon Wright @ 1997-04-29 0:00 ` Robert I. Eachus 0 siblings, 0 replies; 114+ messages in thread From: Robert I. Eachus @ 1997-04-29 0:00 UTC (permalink / raw) In article <x7vd8reudcb.fsf@pogner.demon.co.uk> Simon Wright <simon@pogner.demon.co.uk> writes: dewar@merv.cs.nyu.edu (Robert Dewar) writes: > it is simply > too unusual an idiom (a case against a large number of strings that are > staticaly known at compile time) to be worthwhile. I have trouble thinking > of any reasonable examples ... Another case that does come up is in parsing IFF formated files. Every section has a tag which is treated as an integer, but the tag values are selected to be meaningful. For example one image format used is ILBM (interleaved bit map). Now you can write: type IFF_TAG is (ILBM...); for IFF_TAG use (16#494C424D#,...); case Tag is when ILBM... But it sure would be nice not to have to worry that you declared all those tag values right. (And if I was doing a serious IFF parser, I would write a program to write that type declaration.) -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Nick Roberts 1997-04-26 0:00 ` Robert A Duff @ 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney 1997-04-29 0:00 ` Mats Weber 2 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) Nick says <<As to the property of mutual exclusion - this is the 'essence' of the case statement - the implementation would probably have to test ...>> This is only 50% of the essence. The other half is full coverage, which can have no meaning for extended case statements - so I think it is a bad idea to try to extend case statements to non-discrete types. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar @ 1997-04-26 0:00 ` Matthew Heaney 1997-05-02 0:00 ` Nick Roberts 0 siblings, 1 reply; 114+ messages in thread From: Matthew Heaney @ 1997-04-26 0:00 UTC (permalink / raw) In article <dewar.862079014@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: ><<As to the property of mutual exclusion - this is the 'essence' of the case >statement - the implementation would probably have to test ...>> > >This is only 50% of the essence. The other half is full coverage, which can >have no meaning for extended case statements - so I think it is a bad idea >to try to extend case statements to non-discrete types. Ah, Robert brings order to chaos. I heartily agree. There are *much* more important issues to consider than changing case statements so that they work for non-discrete types. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Matthew Heaney @ 1997-05-02 0:00 ` Nick Roberts 1997-05-04 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Nick Roberts @ 1997-05-02 0:00 UTC (permalink / raw) Matthew Heaney <mheaney@ni.net> wrote in article <mheaney-ya023680002604971931400001@news.ni.net>... > In article <dewar.862079014@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: > > ><<As to the property of mutual exclusion - this is the 'essence' of the case > >statement - the implementation would probably have to test ...>> > > > >This is only 50% of the essence. The other half is full coverage, which can > >have no meaning for extended case statements - so I think it is a bad idea > >to try to extend case statements to non-discrete types. > > Ah, Robert brings order to chaos. I heartily agree. There are *much* more > important issues to consider than changing case statements so that they > work for non-discrete types. I agree that full coverage is an essential part of the case statement, but, with respect, I think Robert is wrong to say that therefore this idea can have 'no meaning' for extended case statements: it seems to me that there would simply have to be a requirement (in the language rules) that there was an 'others' alternative in any such extended case statement, and this would then guarantee coverage (similarly to the rules for case statements whose control expression is of a type which is a formal generic (discrete) type). On the other hand, it could perhaps be argued that one of the precepts of the case statement in Ada has always been that the choices are all static (except for 'others') so that special optimisation could be applied (e.g. a jump table) to increase speed. This would, of course, be impossible for extended case statements (except by overly clever optimisation techniques). Finally, I think I would agree with Matthew that this is probably not a very important issue concerning the design of the Ada language! (So maybe I should shut up now? :-) Nick. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-02 0:00 ` Nick Roberts @ 1997-05-04 0:00 ` Robert Dewar 1997-05-05 0:00 ` Robert A Duff 1997-05-05 0:00 ` Mats Weber 0 siblings, 2 replies; 114+ messages in thread From: Robert Dewar @ 1997-05-04 0:00 UTC (permalink / raw) Nick says <<I agree that full coverage is an essential part of the case statement, but, with respect, I think Robert is wrong to say that therefore this idea can have 'no meaning' for extended case statements: it seems to me that there would simply have to be a requirement (in the language rules) that there was an 'others' alternative in any such extended case statement, and this would then guarantee coverage (similarly to the rules for case statements whose control expression is of a type which is a formal generic (discrete) type).>> But in general we follow the rule in Ada of not using the others clause precisely because it disables an important check. A case statement that requires an others is entirely equivalent to a set of elsif's, so why have an alternative syntax. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-04 0:00 ` Robert Dewar @ 1997-05-05 0:00 ` Robert A Duff 1997-05-05 0:00 ` Mats Weber 1 sibling, 0 replies; 114+ messages in thread From: Robert A Duff @ 1997-05-05 0:00 UTC (permalink / raw) In article <dewar.862718892@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: >But in general we follow the rule in Ada of not using the others clause >precisely because it disables an important check. I follow a rule more like this: Use "others" only if you want that alternative to cover all possibilities not mentioned, INCLUDING THOSE POSSIBILITIES THAT HAVEN'T BEEN INVENTED YET. E.g. for an enumeration type, others should conceptually include all the enumeration literals that somebody might add to the program in some future version. Yes, this implies that "others" is *usually* not a good idea. But it sometimes is a good idea. For example, a lexical analyzer for Ada might have a case_statement on characters to do something in particular for the cases mentioned in the RM as legal tokens, and have a "when others => Error;" alternative. There's really no particular value in listing all the error-characters explicitly. (I use the same rule for "others" in an array aggregate. For record aggregates, I can't remember ever using "others" -- it's not clear to me why it's even allowed.) >... A case statement that >requires an others is entirely equivalent to a set of elsif's, so why >have an alternative syntax. I don't think they're equivalent. With a case statement (with others) you still know that the alternatives are mutually exclusive, and that their evaluation has no dependence on the current state of global variables. You know that all the alternatives are testing against a single value, and you know that expression is evaluated exactly once (e.g. consider translating "case F(X) is ..." into elsif's). You know that the order of the alternatives doesn't matter. You know these things as soon as you see "case" -- with elsif's, you have to examine each condition carefully to gather such information. Using "others" does not damage all of these good things, and knowing these things easily is helpful in reading a program. If I were extending the case_statement, I would try to retain these properties. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-04 0:00 ` Robert Dewar 1997-05-05 0:00 ` Robert A Duff @ 1997-05-05 0:00 ` Mats Weber 1997-05-05 0:00 ` Robert Dewar 1 sibling, 1 reply; 114+ messages in thread From: Mats Weber @ 1997-05-05 0:00 UTC (permalink / raw) Robert Dewar wrote: > But in general we follow the rule in Ada of not using the others clause > precisely because it disables an important check. A case statement that > requires an others is entirely equivalent to a set of elsif's, so why > have an alternative syntax. In case f(g(x)) is when a => ... when b => ... end case; you see immediately, without having to read the whole statement, that a decision is being made that depends only on the value of f(g(x)). Moreover, if f(g(x)) is a long expression, you only have to write it once. if ... elsif does not have these two advantages. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-05 0:00 ` Mats Weber @ 1997-05-05 0:00 ` Robert Dewar 1997-05-06 0:00 ` Matthew Heaney 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-05-05 0:00 UTC (permalink / raw) Mats says <<In case f(g(x)) is when a => ... when b => ... end case; you see immediately, without having to read the whole statement, that a decision is being made that depends only on the value of f(g(x)). Moreover, if f(g(x)) is a long expression, you only have to write it once. if ... elsif does not have these two advantages.>> I can perfectly well live with declare fgx : constant integer := f (g (x)); begin if fgx = a then ... elsif fgx = b then ... end if; end; Yup, it's a little bit longer, but it just does not seem worthwhile confusing the case semantics and adding considerable complexity to the language and its description just to save a few tokens in this case. Actually this example is a big bogus, since it is really implying that the only possible values are a or b, so if the above case is what you mean, and if you really mean to cover all cases, then the above code is equivalent to if f(g(x)) = a then ... else -- = b ... end if; which is actually shorter (8 tokens instead of 11) I don't like introducing extra complexity in languages just for the sake of a bit of syntactical sugar ... A similar example arose during the 9X discussions, where raise x when ... was proposed. \x1adp ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-05 0:00 ` Robert Dewar @ 1997-05-06 0:00 ` Matthew Heaney 1997-05-06 0:00 ` Robert Dewar 1997-05-07 0:00 ` Tucker Taft 0 siblings, 2 replies; 114+ messages in thread From: Matthew Heaney @ 1997-05-06 0:00 UTC (permalink / raw) In article <dewar.862878406@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: >A similar example arose during the 9X discussions, where > > raise x when ... > >was proposed. That's funny, because I was shocked to learn that that wasn't included in Ada 95. To me, that's a quite useful statement (unlike a case statement for non-discrete types - a silly idea), so I don't agree with the comparison. Tuck made the point once on CLA that the designers were trying to be conservative in this revision, and only add things that couldn't be done easily any other way, so I can certainly understand not adding it. One thing he mentioned that didn't go in that probably should have (I think that's what he said...) is procedure P (O : access constant T); I've actually had a use for this kind of thing. It would allow me to take the 'Access of an tagged parameter of mode in: procedure Q (O : in T) is begin P (O'Access); ... As it stands now I can't do that, because the object passed to "access T" has to be mode in out. Bummer. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-06 0:00 ` Matthew Heaney @ 1997-05-06 0:00 ` Robert Dewar 1997-05-07 0:00 ` Tucker Taft 1 sibling, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-05-06 0:00 UTC (permalink / raw) Matthew said <<procedure Q (O : in T) is begin P (O'Access); ... As it stands now I can't do that, because the object passed to "access T" has to be mode in out. Bummer. >> Note that if you are using GNAT, you can use 'Unrestricted_Access in this situation -- of course that may not be portable to other compilers, since it is an implementation dependent attribute. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-06 0:00 ` Matthew Heaney 1997-05-06 0:00 ` Robert Dewar @ 1997-05-07 0:00 ` Tucker Taft 1 sibling, 0 replies; 114+ messages in thread From: Tucker Taft @ 1997-05-07 0:00 UTC (permalink / raw) Matthew Heaney (mheaney@ni.net) wrote: : ... : One thing he mentioned that didn't go in that probably should have (I think : that's what he said...) is : procedure P (O : access constant T); : I've actually had a use for this kind of thing. It would allow me to take : the 'Access of an tagged parameter of mode in: : procedure Q (O : in T) is : begin : P (O'Access); : ... : As it stands now I can't do that, because the object passed to "access T" : has to be mode in out. Bummer. You can declare a named access-to-constant type, and use that instead of an anonymous type. E.g.: type acc_to_con is access constant T; ... procedure P(O : acc_to_con); You will need to use 'Unchecked_Access to call it, though that is not exactly a huge crime in this case (IMHO). : -------------------------------------------------------------------- : Matthew Heaney : Software Development Consultant : <mailto:matthew_heaney@acm.org> : (818) 985-1271 -Tucker Taft stt@inmet.com http://www.inmet.com/~stt/ Intermetrics, Inc. Burlington, MA USA ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Nick Roberts 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar @ 1997-04-29 0:00 ` Mats Weber 1997-05-01 0:00 ` Robert Dewar 2 siblings, 1 reply; 114+ messages in thread From: Mats Weber @ 1997-04-29 0:00 UTC (permalink / raw) Nick Roberts wrote: > As to the property of mutual exclusion - this is the 'essence' of the case > statement - the implementation would probably have to test every choice at > run time in order to check that only one choice evaluates to True (and > raise an exception otherwise). [...] The language definition is not based on any concept like "the essence of the case statement". I don't see any problem with taking the first alternative that fits, like in a UNIX shell, where case does not follow the "essence" but is still very useful (OK, I know, we were talking programming languages :-). Anyway I think that checking the mutual exclusion of case alternatives at run time would be a waste of resources. Doing so at compile time in the static case is a very good feature, and that's why I think the static case should be kept as it is now. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-29 0:00 ` Mats Weber @ 1997-05-01 0:00 ` Robert Dewar [not found] ` <01bc571c$01f3ffc0$5de2b8cd@p5120.bda> 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-05-01 0:00 UTC (permalink / raw) Mats Weber says <<The language definition is not based on any concept like "the essence of the case statement". I don't see any problem with taking the first alternative that fits, like in a UNIX shell, where case does not follow the "essence" but is still very useful (OK, I know, we were talking programming languages :-).>> Sorry that is wrong, the language design very much has a clear notion of the design principles behind case. It is NOT just syntactic sugar for a series of if's. I would find a design such as Mats suggests where case is sometimes just syntactic sugar for if's and sometimes something quite different depending on whether the expressions are involved to be a far less coherent design than the current one. You are proposing introducing a lot of confusion in to the semantic framework, plus a nasty anomoly where adding the keyword constant suddely makes a program illegal (yes I know there are acses of that now). And all you get in return is something that you think is syntactically a bit neater in some cases that do not frequently arise. I am not even sure that I agree that it is syntactically neater. I note that many Ada programmers will prefer if x = 3 then ... elsif x = 72 then ... else ... to case x is when 3 => ... when 72 => ... when others => ... end case; The use of case here, though legal, is conceptually a little bit removed from the notions of exclusion and coverage that are fundamental to the case statement -- not technically by conceptually! That is why you will find many programmers preferring the first form. I am not saying it should be preferred, and I am not saying the case is wrong, and I do not particularly want to hear people telling me that they personally prefer the case here -- of course there are such people too. The point is that trying to extend the case statement is based on an implicit assumption that in the above examples, the more verbose case statement is preferable. ^ permalink raw reply [flat|nested] 114+ messages in thread
[parent not found: <01bc571c$01f3ffc0$5de2b8cd@p5120.bda>]
* Re: Equality operator overloading in ADA 83 [not found] ` <01bc571c$01f3ffc0$5de2b8cd@p5120.bda> @ 1997-05-03 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-05-03 0:00 UTC (permalink / raw) Bob Klungle said <<Just for the record, I just finished a discussion with Rational re the Verdix 83 compiler. In a routine we were using (single_value_decomposition), there were several instances of floating point tests for equality (to 0.0). The code worked perfectly with the -O0 option (no optimization), but when any optimization was allowed, this test failed in various ways (apparently not predictable according to Rational). Their statement was that the floating "=" met the 83 LRM and they were not going to change it. They said we had to overload the "=" operator to effectively test for abs(x - y) > delta. That is what they do and it works.>> This sounds extremely dubious, we would have to see the code ... Zero is a model number, so for example x := 0.0; y := 0.0; x := x / 2.0; if x = y then Put_Line ("Worked"); end if; must print Worked, a compiler that does not print worked is broken. It would be really interesting to see the precise code in question ... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Robert A Duff 1997-04-26 0:00 ` Nick Roberts @ 1997-04-27 0:00 ` Robert Dewar 1997-04-27 0:00 ` Fergus Henderson 1 sibling, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-27 0:00 UTC (permalink / raw) Bob Duff says <<Why finite? The "essence" is that you have a bunch of mutually exclusive possibilities, and that you cover all the cases, as in: case To_Lower(X) is -- Not Ada! when "begin" => Do_This; when "end" => Do_That; when others => Do_The_Other; end case; Ada's choice is to check those rules at compile time, but that's not part of the "essence". It's a reasonable choice, though. Of course, I've written "when others => raise ...;" sometimes. But either way, it doesn't require forbidding strings and other types. That decision is based on ease-of-implementation and ease-of-efficient-implementation, I think. I'm not arguing that Ada should have this feature ...>> Here I simply disagree, I find the semantics of checking that all cases are covered (in the absence of others, one should almost always avoid the use of others in case statements), to be a fundamental part of the design semantics of the case statement, that distinguishes it in a fundamental way from the switch of Algol-60 or in BCPL (I mention this because if I remember right, BCPL does allow strings, and expect an implementation to build a hash table where neessary). In the case of strings, you would *always* have to use others if you want to preserve this completeness property. I think that extending case to handle strings would confuse this important function of the case statement, and since it is only a matter of minor syntactic sugar (you think one syntax looks better than another), I think it is unimportant. I still think that the utility is marginal in real programs, I looked for the elsif pattern that would correspond to this case sequence, and found *very* few examples in the millions of lines of code in our regression suite (always an interesting place to look, since it represents code from many places). ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-27 0:00 ` Robert Dewar @ 1997-04-27 0:00 ` Fergus Henderson 1997-04-27 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Fergus Henderson @ 1997-04-27 0:00 UTC (permalink / raw) dewar@merv.cs.nyu.edu (Robert Dewar) writes: >I still think that the utility is marginal in real programs, I looked for >the elsif pattern that would correspond to this case sequence, and found >*very* few examples in the millions of lines of code in our regression >suite (always an interesting place to look, since it represents code from >many places). FWIW, I have some data that may be relevant. The Mercury language includes support for the equivalent of string case statements, and for switches that meet a minimum size requirement (8 cases), the Mercury compiler generates hash tables to index such switches. I did a quick grep for `hash_string' in the generated code, and found that for the Mercury compiler itself (108 thousand lines of Mercury source, or 80 thousand if you exclude whitespace and comment lines), there where 15 such occurrences, spread over 12 of the 126 modules, or about one for every 5 thousand non-comment non-whitespace line of code. (That figure doesn't count string switches with 7 or less cases, for which the Mercury compiler currently generates code using if-then-else chains.) I leave it to the reader to judge what conclusions should be drawn from this data. -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit" PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-27 0:00 ` Fergus Henderson @ 1997-04-27 0:00 ` Robert Dewar 1997-04-28 0:00 ` Fergus Henderson 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-27 0:00 UTC (permalink / raw) Fergus said <<The Mercury language includes support for the equivalent of string case statements, and for switches that meet a minimum size requirement (8 cases), the Mercury compiler generates hash tables to index such switches. I did a quick grep for `hash_string' in the generated code, and found that for the Mercury compiler itself (108 thousand lines of Mercury source, or 80 thousand if you exclude whitespace and comment lines), there where 15 such occurrences, spread over 12 of the 126 modules, or about one for every 5 thousand non-comment non-whitespace line of code. (That figure doesn't count string switches with 7 or less cases, for which the Mercury compiler currently generates code using if-then-else chains.) I leave it to the reader to judge what conclusions should be drawn from this data.>> Interesting: I really can't see any utility in this feature in a compiler so it is a surprise to me that it is used in any compiler ... Usually you want to do all string recognizion in the context of a general names table that includes user defined words as well as system words. Fergus can you give a hint of typical example of how this is used. Of course the data you present give no information as to the value of this optimization ... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-27 0:00 ` Robert Dewar @ 1997-04-28 0:00 ` Fergus Henderson 1997-04-28 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Fergus Henderson @ 1997-04-28 0:00 UTC (permalink / raw) dewar@merv.cs.nyu.edu (Robert Dewar) writes: >Fergus said > ><<The Mercury language includes support for the equivalent of >string case statements [...] >I leave it to the reader to judge what conclusions should be >drawn from this data.>> > >Interesting: I really can't see any utility in this feature in a compiler >so it is a surprise to me that it is used in any compiler ... Usually >you want to do all string recognizion in the context of a general names >table that includes user defined words as well as system words. Fergus >can you give a hint of typical example of how this is used. In examples in the Mercury compiler, the strings involved are - the names of operators - the names of procedures for which the compiler generates inline code - names to special-case when doing name mangling ... Some examples I see use Mercury predicates as small in-memory read-only relational databases; for example: % areas in 1000s of square miles :- pred area(string, int). :- mode area(in, out). area("china", 3380). area("india", 1139). area("ussr", 8708). area("usa", 3609). area("indonesia", 570). area("japan", 148). ... I suppose in Ada you could handle these sorts of examples by declaring a constant array of records, making sure that the array was sorted, and using binary search. -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit" PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-28 0:00 ` Fergus Henderson @ 1997-04-28 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-28 0:00 UTC (permalink / raw) Fergus said << - the names of operators - the names of procedures for which the compiler generates inline code - names to special-case when doing name mangling>> OK, that's a very unusual (and I would think rather inconvenient and inefficient) approach. The normal way of handling strings like this in a compiler is to enter them into a hashed name table early on, and then use keys to reference them from there on -- that way you do not have strings wandering around the place. That's certainly something I teach as a standard compiler technique in my compilers course. For an example, see the Namet package in GNAT. Certainly if names are wandering around as strings in your compiler, I see how you would have case statements of this kind around! Note that if you use a discrete type for the key, you can then write case statements, for example, we could write in GNAT for the test of sopecial names of procedures that atr intrinsic (the second case you mention) case Name (Node) is when Name_Divide => when Name_Plus => ... we would of course need a when others, but that you need naturally in this case anyway. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Robert A Duff 1997-04-24 0:00 ` Robert Dewar @ 1997-04-25 0:00 ` Kevin Cline 1997-04-25 0:00 ` Mats Weber ` (2 more replies) 1997-04-25 0:00 ` Mats Weber 1997-04-27 0:00 ` Geert Bosch 3 siblings, 3 replies; 114+ messages in thread From: Kevin Cline @ 1997-04-25 0:00 UTC (permalink / raw) bobduff@world.std.com (Robert A Duff) wrote: > >The problem is that you don't know where it goes -- for example, suppose >there's a Sort generic. You don't know if it's defined in terms of "<=" >or ">=" -- and it doesn't matter, so long as nobody redefines one >without redefining the other. You should know. All comparison functions used by a generic should be generic formal parameters with defaults. The C++ standards committee wrestled with this one while defining the C++ Standard Template Library, (which provides a generic sort) and decided that all STL containers and functions would use only "<" and "=", an admirable decision in my opinion. It makes the implementation of the STL a teeny tiny bit harder, but eases the task for all users. >OK, but then if I redefine "<" on a scalar type, should ">=" change? >After all, ">=" is (or could be) defined as "not <". Only for totally-ordered sets. It is useful to redefine "<" and ">" to model partial orderings, in which case >= is not equivalent a < b. >Historical note: I believe the Red language tried to make sure >overloadings of the comparison ops "made sense" in this way -- you could >overload two of them, and the other four would automatically change. What a narrow view to take! ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Kevin Cline @ 1997-04-25 0:00 ` Mats Weber 1997-04-27 0:00 ` Robert Dewar 1997-04-25 0:00 ` Mats Weber 1997-04-25 0:00 ` Robert A Duff 2 siblings, 1 reply; 114+ messages in thread From: Mats Weber @ 1997-04-25 0:00 UTC (permalink / raw) > >OK, but then if I redefine "<" on a scalar type, should ">=" change? > >After all, ">=" is (or could be) defined as "not <". > > Only for totally-ordered sets. It is useful to redefine "<" and ">" to model > partial orderings, in which case >= is not equivalent a < b. If it's done right, the definition of "=" and "<" is enough to construct the others, even for non-totally ordered sets. Just don't make the mistake of making "<" defined as not ">=": a <= b means a < b or a = b a > b means b < a a >= b meanss a > b or a = b The case where this does not work is when "<=" is not an ordering relation (in the mathematical sense). Non-total orders such as set inclusion work perfectly. And yes, I think that there should be an automatic redefinition in Ada once "=" and one of "<", ">", ">=", "<=" are defined (but I realize it's too late now, this should have been done in Ada 83). ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Mats Weber @ 1997-04-27 0:00 ` Robert Dewar 1997-04-29 0:00 ` Mats Weber 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-27 0:00 UTC (permalink / raw) Mats says <<And yes, I think that there should be an automatic redefinition in Ada once "=" and one of "<", ">", ">=", "<=" are defined (but I realize it's too late now, this should have been done in Ada 83).>> This would be a terrible idea, since it would build in serious inefficiencies. A typical way of implementing comparisons for a complex type is to have a single comparison routine that indicates the compare status (LT, EQ, GT) and then have the operators be a simple wrapper around this routine. Your automatically constructed cases would introduce serious inefficiencies, typically doubling the time of some complex comparisons. FOr instance, you define "<=" as "<" or "=", but look at the following from the GNAT ureal package (arbitrary precision reals): ----------- -- UR_Le -- ----------- function UR_Le (Left, Right : Ureal) return Boolean is begin return not (Right < Left); end UR_Le; (and the "<=" operator renames UR_Le) Your approach would make this important operation take twice as long ... Yes, I suppose I could get around it with caching, but that is messy to do in a task safe manner. I don't like this idea at all, and if it was ever suggested for Ada 83 (I can't remember it having come up, but it must be something the design team considered), then it was correctly rejected in my view. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-27 0:00 ` Robert Dewar @ 1997-04-29 0:00 ` Mats Weber 0 siblings, 0 replies; 114+ messages in thread From: Mats Weber @ 1997-04-29 0:00 UTC (permalink / raw) Robert Dewar wrote: > > Mats says > > <<And yes, I think that there should be an automatic redefinition in Ada > once "=" and one of "<", ">", ">=", "<=" are defined (but I realize it's > too late now, this should have been done in Ada 83).>> > > This would be a terrible idea, since it would build in serious inefficiencies. > A typical way of implementing comparisons for a complex type is to have a > single comparison routine that indicates the compare status (LT, EQ, GT) and > then have the operators be a simple wrapper around this routine. > > [...] When efficiency is important, the programmer can define all five relational operators explicitly (and inline them, etc.). When he is lazy, he can define just two. I don't really see the problem. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Kevin Cline 1997-04-25 0:00 ` Mats Weber @ 1997-04-25 0:00 ` Mats Weber 1997-04-25 0:00 ` Robert Dewar 1997-04-25 0:00 ` Robert A Duff 2 siblings, 1 reply; 114+ messages in thread From: Mats Weber @ 1997-04-25 0:00 UTC (permalink / raw) > >Historical note: I believe the Red language tried to make sure > >overloadings of the comparison ops "made sense" in this way -- you could > >overload two of them, and the other four would automatically change. > > What a narrow view to take! Really ? Then show me an example where you think it's reasonable to have a < b not equivalent to b > a or a <= b not equivalent to a < b or a = b ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Mats Weber @ 1997-04-25 0:00 ` Robert Dewar 1997-04-29 0:00 ` Mats Weber 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-25 0:00 UTC (permalink / raw) Mats said <<Really ? Then show me an example where you think it's reasonable to have a < b not equivalent to b > a or a <= b not equivalent to a < b or a = b>> Well equivalent is a tricky word, Mats I certainly hope you realize that with standard Ada floating-point semantics, you are not guaranteed that these pairs of possibilities wll generate identical boolean results! I can also easily see someone defining > or <= to mean something completely different from comparison on a type for which comparisons make no sense (For example <= looks a bit like an assignment ..._ ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Robert Dewar @ 1997-04-29 0:00 ` Mats Weber 1997-05-01 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Mats Weber @ 1997-04-29 0:00 UTC (permalink / raw) Robert Dewar wrote: > > Mats said > > <<Really ? Then show me an example where you think it's reasonable to have > a < b not equivalent to b > a > or > a <= b not equivalent to a < b or a = b>> > > Well equivalent is a tricky word, Mats I certainly hope you realize that > with standard Ada floating-point semantics, you are not guaranteed that > these pairs of possibilities wll generate identical boolean results! Yes, I do. But given good definitions of "=" and "<" for a floating point type, applying my definitions will yield ">", "<=" and "<=" that are just as good. Defining "good" here is tricky, e.g. you are not supposed to use "=" for floating point, but rather something like abs (a - b) < epsilon * (abs a + abs b) > I can also easily see someone defining > or <= to mean something completely > different from comparison on a type for which comparisons make no sense > (For example <= looks a bit like an assignment ..._ ... if opertors could be procedures, or functions could have parameter modes other than in, but that happens not to be the case. Ada has quite a conservative philosophy on operator redefinition, why not stick to it ? ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-29 0:00 ` Mats Weber @ 1997-05-01 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-05-01 0:00 UTC (permalink / raw) <<Yes, I do. But given good definitions of "=" and "<" for a floating point type, applying my definitions will yield ">", "<=" and "<=" that are just as good. Defining "good" here is tricky, e.g. you are not supposed to use "=" for floating point, but rather something like abs (a - b) < epsilon * (abs a + abs b)>> That is a common myth, particularly among those who do not do serious analysis of floating-point code. The equality operation for floating-point values is well defined, and is useful. The expression you give above with epsilon is sometimes useful (though dangerous because of intermediate overflow), but is a quite different operation. The notion that you should always use the epsilon approach is wrong. There are lots of examples of numerical algorithms where plain equality works fine (and is far more efficient), and there are cases of algorithms where ONLY the plain equality will work! ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Kevin Cline 1997-04-25 0:00 ` Mats Weber 1997-04-25 0:00 ` Mats Weber @ 1997-04-25 0:00 ` Robert A Duff 2 siblings, 0 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-25 0:00 UTC (permalink / raw) In article <33671d9c.5046069@news.airmail.net>, Kevin Cline <clines@delete_this.airmail.net> wrote: >You should know. All comparison functions used by a generic should be generic >formal parameters with defaults. Probably a good idea for "<" and sorting. But it doesn't solve the problem. How does the compiler know whether the generic is making certain assumptions (like "A < B and B < C" implies "A < C")? We're talking about language semantics, here: you either have to define precise language rules that ensure the above property, or you have to say what happens if that property doesn't hold (and lots of other properties one could imagine). It's not fair to rely on programmer's good taste. Do you believe that Text_IO.Integer_IO should have generic formal functions for "+", "/", "mod", etc? Even if it did, you still wouldn't know exactly how they are used without looking at the generic body (which I'm afraid is not in the RM). There are many different algorithms for converting integers to string form, and redefining "/" might break some such algorithms, and not others. >>OK, but then if I redefine "<" on a scalar type, should ">=" change? >>After all, ">=" is (or could be) defined as "not <". > >Only for totally-ordered sets. It is useful to redefine "<" and ">" to model >partial orderings, in which case >= is not equivalent a < b. We're talking about what the language semantics should do automatically for you. You have to say "yes" or "no". You can't say "only for totally-ordered sets" (unless you give the compiler some way of telling whether you meant it to be a totally-ordered set, which sounds like a can of worms to me). - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Robert A Duff 1997-04-24 0:00 ` Robert Dewar 1997-04-25 0:00 ` Kevin Cline @ 1997-04-25 0:00 ` Mats Weber 1997-04-27 0:00 ` Geert Bosch 3 siblings, 0 replies; 114+ messages in thread From: Mats Weber @ 1997-04-25 0:00 UTC (permalink / raw) Robert A Duff wrote: > This should compare a billion numbers for equality with X, using the > user's "=" operator? Hmm. Perhaps a reasonable thing for a new > language, but rather out of the question for a "language revision" like > Ada 9X. Of course, if one could redefine "in".... OK, it's a tough one. One idea could be that "in" works according to the relational operators (see my other post in this thread). Another idea is to leave the case statement alone, i.e. use predefined equality for case. Still another idea (maybe the best one) is to forbid case when "=" is redefined. > I would also like to see case statements on strings, but that's a much > higher level language than Ada, I think. This was in one of the Ada 9X drafts, and I liked the proposal. It was defined as equivalent to a sequence of if elsif, but I think with better readability. > >One can still keep the advantage of having to cover all possible values > >when the selector's subtype is static and discrete with no "=" > >redefinition. Otherwise, there would be a when others => null by default > >as the last choice. > > Bad choice. Better to make it a run-time error. I like the idea of being able to make sure at compile time that I have covered all cases. So I would keep it, but it's really a matter of personal preference. > >For instances of predefined packages such as Text_IO.Integer_IO with > >types whose arithmetic has been messed with, I think it's OK if they > >don't work correctly. It's easy to make the few needed type conversions > >to make sure IO works with such types, which require special care > >anyway. > > I might agree, except that I haven't the foggiest notion of how one > specifies this precisely. I mean, the RM doesn't *say* > Text_IO.Integer_IO needs to do a "/" by 10. I just happen to know that > the implementation *might*. So what should the *spec* of Text_IO say > about types that have redefined "/"? Or "mod" or "rem" or "-" etc.? I would say that the behavior is not specified by the language, and the compiler could give a warning when such an instantiation is made. > >I think that the argument of backward compatibility with Ada 83 is not > >that important (just my opinion). > > Indeed (just your opinion). In the Ada 9X project, it was an overriding > concern. In Ada 83, the problem was quite different. You could redefine "=" only for limited types, and inside a generic, you couldn't access "=" of a formal limited type unless it was explicitly given as a generic formal parameter. So there was no reemergence of "=" anywhere and the language was "clean" in that respect. Other operators such as "+" and "<" could reemerge, but I think it's fair to say that they are less important than "=". (Also, there was the unexpected possibility of redefining "=" for non-limited types, but I think that this is pathological enough not to be worried about). > >... I think that if someone redefines an > >operator for a type, then he probably has a good reason to do so, and > >that operator becomes part of the abstraction provided by that type and > >must stick with it wherever the types goes, with no exception. > > The problem is that you don't know where it goes -- for example, suppose > there's a Sort generic. You don't know if it's defined in terms of "<=" > or ">=" -- and it doesn't matter, so long as nobody redefines one > without redefining the other. This can be a problem, but only if "<" is redefined while leaving the other relationals untouched, with a meaning that does not match the "<" redefinition, which is very questionable practice. It's prefectly OK to define only "<" and "=" when the type is private (i.e. no predefined ordering operators need to be hidden). Here again, I think that the preservation of the abstraction (redefinition of the ordering) is the most important point. Anyway you can mess up pretty bad with operator redefinition, with or without reemergence, for instance by defining an "=" that is not an equivalence relation (in the mathematical sense). > OK, but then if I redefine "<" on a scalar type, should ">=" change? > After all, ">=" is (or could be) defined as "not <". > > Historical note: I believe the Red language tried to make sure > overloadings of the comparison ops "made sense" in this way -- you could > overload two of them, and the other four would automatically change. Good idea IMO (see my other post). > P.S. I have a lot of sympathy for your point of view. > I'm just griping because it's hard to fit in to Ada. Nice to hear that I am not alone. I remember the pleasure I had reading the phrase "we are eliminating the reemergence of predefined operators in Ada 9X" in some draft Ada 9X RM. I was so upset to see it removed. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Robert A Duff ` (2 preceding siblings ...) 1997-04-25 0:00 ` Mats Weber @ 1997-04-27 0:00 ` Geert Bosch 3 siblings, 0 replies; 114+ messages in thread From: Geert Bosch @ 1997-04-27 0:00 UTC (permalink / raw) Robert A Duff (bobduff@world.std.com) wrote: ``OK, but then if I redefine "<" on a scalar type, should ">=" change? After all, ">=" is (or could be) defined as "not <". '' No, I don't think you can do that. For a program that finds all anagrams of some text, I defined a "Signature" type. A signature of a string is an (long) integer sized hash-value, that makes it possible to efficiently implement the following partial ordering: Given strings A and B with signatures SA and SB: when SA > SB, then A is not a partial anagram of B; ie. A cannot be made with the characters of B. In this case SA > SB does not imply that SB < SA. Of course you might argue that redefining comparison operators to implement a type with partial ordering is a "bad thing". I think it makes the program much more readable. Regards, Geert ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Mats Weber 1997-04-24 0:00 ` Matthew Heaney 1997-04-24 0:00 ` Robert A Duff @ 1997-04-28 0:00 ` Robert Dewar 1997-04-29 0:00 ` Mats Weber 1997-04-29 0:00 ` Matthew Heaney 1997-04-28 0:00 ` Robert Dewar 3 siblings, 2 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-28 0:00 UTC (permalink / raw) Mats said <,I think that the argument of backward compatibility with Ada 83 is not that important (just my opinion). I think that if someone redefines an operator for a type, then he probably has a good reason to do so, and that operator becomes part of the abstraction provided by that type and must stick with it wherever the types goes, with no exception. >> To ignore the compatibility issue here would have been a serious mistake. What frequently happens is that in the body, where a private type is visible, you don't really want the redefined equality at all, but you get it some of the time, and you have to convert etc to get rid of it, which of course is necessary in both Ada 83 and Ada 95 code. But if you extend the reach of this equality operator, then it will extend into these bodies -- and that easily cause incomaptibilities of the worst possible kind (i.e. Ada 83 code would compile fine, but give subtly different results). The design process of Ada 9x was, quite properly in my view, extremely conservative with respect to this kind of incompatibility. It was considered to be worth while incurring some such isntances for 8-bit characters (which in legal terms were allowed in Ada 83 anyway), but certainly not for tagged types. I must say that I here a lot of sturm und drang with respect to this issue (equality not composing), but I must say I have never found this a limitation in real code. Array and record equality is rare in any case, and is even rarer in cases where component equality has been redefined. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-28 0:00 ` Robert Dewar @ 1997-04-29 0:00 ` Mats Weber 1997-04-29 0:00 ` Robert A Duff 1997-05-01 0:00 ` Robert Dewar 1997-04-29 0:00 ` Matthew Heaney 1 sibling, 2 replies; 114+ messages in thread From: Mats Weber @ 1997-04-29 0:00 UTC (permalink / raw) Robert Dewar wrote: > > Mats said > > <,I think that the argument of backward compatibility with Ada 83 is not > that important (just my opinion). I think that if someone redefines an > operator for a type, then he probably has a good reason to do so, and > that operator becomes part of the abstraction provided by that type and > must stick with it wherever the types goes, with no exception. > >> > > To ignore the compatibility issue here would have been a serious mistake. > > What frequently happens is that in the body, where a private type is > visible, you don't really want the redefined equality at all, but you > get it some of the time, and you have to convert etc to get rid of it, > which of course is necessary in both Ada 83 and Ada 95 code. But if > you extend the reach of this equality operator, then it will extend > into these bodies -- and that easily cause incomaptibilities of the > worst possible kind (i.e. Ada 83 code would compile fine, but give > subtly different results). This (Ada 83 code behaving in a different way with reemergence removed) is not possible with the "=" operator because of the restrictions that Ada 83 put on it. It can only happen with other operators, e.g. numeric types for which "+", "-", etc. have been redefined. The difference in behavior between tagged and non-tagged types, especially in the case where a type is not visibly tagged, is particularly ugly IMO. Just look at how the "=" problem was overlooked for all types in the language libraries. This can also cause maintenance problems: a private non-tagged type could at some time be made invisibly tagged for some reason (inheritance, make it a controlled type, ...) without changing the visible part of the package that defines it. Then all uses of the type must be checked for reemergence problems. So much for the contract model... the user of a private type doesn't care how it is implemented, right ? > The design process of Ada 9x was, quite properly in my view, extremely > conservative with respect to this kind of incompatibility. It was considered > to be worth while incurring some such isntances for 8-bit characters (which > in legal terms were allowed in Ada 83 anyway), but certainly not for > tagged types. In this case, I think that redefining "=" for non-tagged non-limited types should have remained forbidden. > I must say that I here a lot of sturm und drang with respect to this issue > (equality not composing), but I must say I have never found this a > limitation in real code. Array and record equality is rare in any case, > and is even rarer in cases where component equality has been redefined. I disagree, consider this: generic type Element is private; package Set is ... end; type User_Id is private; function "=" (L, R : User_Id) return Boolean; type Group_Id is private; function "=" (L, R : Group_Id) return Boolean; type User_and_Group is record User : User_Id; Group : Group_Id; end record; package User_and_Group_Sets is new Sets(Element => User_And_Group); -- Broken: predefined "=" reemerges unless User_Id and Group_Id -- are (invisibly) tagged types. To see how it is broken, look at -- what happens if User_Id and Group_Id are implemented as -- access String. I find this kind of composition all the time in production (delivered, working, got payed for it :-) code. That's what records are for, after all: the cartesian product of types. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-29 0:00 ` Mats Weber @ 1997-04-29 0:00 ` Robert A Duff 1997-04-29 0:00 ` Matthew Heaney 1997-05-01 0:00 ` Robert Dewar 1 sibling, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-04-29 0:00 UTC (permalink / raw) In article <3365D08F.26EA@elca-matrix.ch>, Mats Weber <Mats.Weber@elca-matrix.ch> wrote: >The difference in behavior between tagged and non-tagged types, >especially in the case where a type is not visibly tagged, is >particularly ugly IMO. In retrospect, I tend to agree that we should have gone a wee bit further in composability of "=". Especially since "=" on nonlimited types is a new feature (except for the Goodenough trick, which is silly to worry about). And because "=" is already special anyway -- the magic "/=" you get for free, the fact that dispatching calls to "=" do a different sort of tag check, etc. However, I'm not quite sure how far we should have gone. Not very. Certainly not to extending composability to other operators, and certainly not affecting the semantics of "in" or "case". Perhaps I'd consider such things for a new language, but not for Ada 9X. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-29 0:00 ` Robert A Duff @ 1997-04-29 0:00 ` Matthew Heaney 1997-05-02 0:00 ` Tucker Taft 0 siblings, 1 reply; 114+ messages in thread From: Matthew Heaney @ 1997-04-29 0:00 UTC (permalink / raw) In article <E9EKDn.77q@world.std.com>, bobduff@world.std.com (Robert A Duff) wrote: >In retrospect, I tend to agree that we should have gone a wee bit >further in composability of "=". Especially since "=" on nonlimited >types is a new feature (except for the Goodenough trick, which is silly >to worry about). And because "=" is already special anyway -- the magic >"/=" you get for free, the fact that dispatching calls to "=" do a >different sort of tag check, etc. > >However, I'm not quite sure how far we should have gone. Not very. >Certainly not to extending composability to other operators, and >certainly not affecting the semantics of "in" or "case". Perhaps I'd >consider such things for a new language, but not for Ada 9X. Yes, I agree; that about sums it up nicely. I feel that the language should have guaranteed that equality composes, when redefined for nonlimited, untagged types. I'm not passionate about other operators (how many times do you have "<" for records?). Even if a user redefines equality, he should implement it so that the behavior is identical to predefined equality. It's not any different when overriding a primitive operation inherited from a (tagged) parent: it's the same operation, but with a different implementation. I'm not going to maliciously override an Area function to return Circumference instead. And I'm not going to override equality to return anything other than equality; the behavior will be the same. So why not let equality compose? Perhaps we can repair this...um..."feature" of the language in Ada 0X. :-) Matt -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-29 0:00 ` Matthew Heaney @ 1997-05-02 0:00 ` Tucker Taft 1997-05-02 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Tucker Taft @ 1997-05-02 0:00 UTC (permalink / raw) Matthew Heaney (mheaney@ni.net) wrote: : In article <E9EKDn.77q@world.std.com>, bobduff@world.std.com (Robert A : Duff) wrote: : >In retrospect, I tend to agree that we should have gone a wee bit : >further in composability of "=". Especially since "=" on nonlimited : >types is a new feature (except for the Goodenough trick, which is silly : >to worry about). And because "=" is already special anyway -- the magic : >"/=" you get for free, the fact that dispatching calls to "=" do a : >different sort of tag check, etc. : > : >However, I'm not quite sure how far we should have gone. Not very. : >Certainly not to extending composability to other operators, and : >certainly not affecting the semantics of "in" or "case". Perhaps I'd : >consider such things for a new language, but not for Ada 9X. : Yes, I agree; that about sums it up nicely. I feel that the language : should have guaranteed that equality composes, when redefined for : nonlimited, untagged types. I'm not passionate about other operators (how : many times do you have "<" for records?). One suggestion which was made (a bit late) was to make a user-defined "=" on records the "official" "=" for the record type, and have the predefined "=" never reemerge for records. This is just expanding the current rule for tagged records to apply to all record types. Since things like "case" don't apply to record types, this imposes essentially no additional burden on the implementation. In retrospect, treating all records specially in this way, rather than just "tagged" records, might have been a better choice. On the other hand, I agree with Robert that using "=" on records is rare to begin with, and gets extremely rare when you start talking about arrays of records, or records of records. Reemergence inside generics is perhaps the real issue, but there, you can always import the "=" operator explicitly, with a default of "<>", so the current state isn't too bad. A part of the rationale for the Ada 95 choice related to the rules for overriding primitive operators/subprograms. For untagged types, the Ada 83 rules were preserved, where only type conformance was required for overriding. For tagged types, we impose a stricter subtype conformance on overriding of primitive operators/subprograms. Without this stricter conformance rule, reemergence in a generic is almost required to avoid bizarre contract model violations. This partially explains why operators and other primitive subprograms reemerge in a generic for a formal untagged derived type as well. One might want to consider going to a stricter conformance rule for overriding of primitives for all record types, rather than just for tagged record types, as part of also eliminating reemergence of operators and other primitives of all record types. As one example of where reemergence is desirable, there are generic packages which rely on arithmetic operators to have their normal effects. For example, a generic package like Text_IO.Integer_IO might very well do some computation to convert to or from a string representation of an integer. If the user has done some bizarre overriding of the arithmetic operators for a particular integer type, it is quite likely that a generic like Text_IO.Integer_IO would act bizarrely if the predefined operators did not reemerge. This kind of problem does not seem to be as big an issue with overriding of the equality operator of a non-numeric type. Anyway, rest assured that this particular issue of operator reemergence was debated hotly several times during the Ada 95 process. The upward compatibility of the final choice was a powerful reason in its favor, but it wasn't the only one... : ... : Matt : -------------------------------------------------------------------- : Matthew Heaney : Software Development Consultant : <mailto:matthew_heaney@acm.org> : (818) 985-1271 -- -Tucker Taft stt@inmet.com http://www.inmet.com/~stt/ Intermetrics, Inc. Burlington, MA USA ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-02 0:00 ` Tucker Taft @ 1997-05-02 0:00 ` Robert Dewar 1997-05-02 0:00 ` Robert A Duff 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-05-02 0:00 UTC (permalink / raw) Tucker said <<One suggestion which was made (a bit late) was to make a user-defined "=" on records the "official" "=" for the record type, and have the predefined "=" never reemerge for records. This is just expanding the current rule for tagged records to apply to all record types. Since things like "case" don't apply to record types, this imposes essentially no additional burden on the implementation.>> This sounds wrong (no additional burden). If you are using shared generics, then this means that you *always* have to provide a thunk for record equality for every record type, even in the (overwhelmingly common) case where you don't do equality checking in any case in the body. This causes extra overhead at runtime, which cannot be got rid of. Thought: an interesting optimization in an Ada compiler would be to recognize a tagged type that had no dispatching primitives (make any primitives you have use 'Class), and then have the implementation avoid generating a dispatch table in this case (perhaps you would need a pragma to disable extensions as well). Then you would be able to make equality compose without the extra overhead of a tagged type at runtime ... (I am talking here not of ideal language design considerations, but practical considerations given Ada 95 as it is!) ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-02 0:00 ` Robert Dewar @ 1997-05-02 0:00 ` Robert A Duff 1997-05-03 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-05-02 0:00 UTC (permalink / raw) In article <dewar.862576384@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: >This sounds wrong (no additional burden). If you are using shared generics, >... If you're using the "always-share" model, then there so much extra overhead anyway, that I wouldn't cry about a little more. If you're using the "sometimes-share" model, then simply don't share when it causes overhead. This requires global (link-time) knowledge. Or let the programmer tell you when to share. >Thought: an interesting optimization in an Ada compiler would be to >recognize a tagged type that had no dispatching primitives (make any >primitives you have use 'Class), and then have the implementation >avoid generating a dispatch table in this case (perhaps you would >need a pragma to disable extensions as well). A compiler can do this optimization in the presence of pragma Restrictions(No_Dispatch). An implementation-defined pragma could make the granularity finer. (Of course, if you're inventing pragmas, you could just as well invent pragma Compose_Eq.) - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-02 0:00 ` Robert A Duff @ 1997-05-03 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-05-03 0:00 UTC (permalink / raw) Robert Duff says <<If you're using the "always-share" model, then there so much extra overhead anyway, that I wouldn't cry about a little more.>> I think that is an exaggeration. How much overhead is involved depends on the architecture. For example, on the old Rational machine, the overhead from always share was quite low ... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-29 0:00 ` Mats Weber 1997-04-29 0:00 ` Robert A Duff @ 1997-05-01 0:00 ` Robert Dewar 1 sibling, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-05-01 0:00 UTC (permalink / raw) <<This (Ada 83 code behaving in a different way with reemergence removed) is not possible with the "=" operator because of the restrictions that Ada 83 put on it. It can only happen with other operators, e.g. numeric types for which "+", "-", etc. have been redefined.>> That's false, we all know how to redefine equality in Ada 83 .... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-28 0:00 ` Robert Dewar 1997-04-29 0:00 ` Mats Weber @ 1997-04-29 0:00 ` Matthew Heaney 1997-05-01 0:00 ` Robert Dewar 1 sibling, 1 reply; 114+ messages in thread From: Matthew Heaney @ 1997-04-29 0:00 UTC (permalink / raw) In article <dewar.862275693@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: >What frequently happens is that in the body, where a private type is >visible, you don't really want the redefined equality at all, but you >get it some of the time, and you have to convert etc to get rid of it, >which of course is necessary in both Ada 83 and Ada 95 code. But if >you extend the reach of this equality operator, then it will extend >into these bodies -- and that easily cause incomaptibilities of the >worst possible kind (i.e. Ada 83 code would compile fine, but give >subtly different results). > I don't accept this argument about "incompatibilities" in Ada 83 code, because the BEHAVIOR of equality never changes, only the implementation. If a programmer overrides equality to have different behavior from predefined equality, then of course that's an error, no different than overriding addition to mean subtraction. >I must say that I here a lot of sturm und drang with respect to this issue >(equality not composing), but I must say I have never found this a >limitation in real code. Array and record equality is rare in any case, >and is even rarer in cases where component equality has been redefined. Perhaps our experience is different, as I see record comparisons ALL the time. One of the reasons one uses a type like Bounded_String is because he needs a constrained string for a record component: package String_80 is new Ada.String.Bounded.Generic_Bounded_Length (80); type R is record S : String_80; ...; end record; A programmer isn't thinking as he compares objects of type R, "Gee, I can't assume equality composes." He just compares them, and just assumes equality always works as expected. Direct array comparisons are admittedly less popular, but array comparisons DO manifest themselves when an array is used to implement a bounded data structure. I see bounded buffers all the time, to implement I/O across an external interface, for example. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-29 0:00 ` Matthew Heaney @ 1997-05-01 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-05-01 0:00 UTC (permalink / raw) <<I don't accept this argument about "incompatibilities" in Ada 83 code, because the BEHAVIOR of equality never changes, only the implementation. If a programmer overrides equality to have different behavior from predefined equality, then of course that's an error, no different than overriding addition to mean subtraction.>> What do you mean? The only use of redefining equality is precisely when the predefined equality is quite wrong. FOr a typ[ical example, see the definition of "=" on type Uintp in the GNAT sources. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Mats Weber ` (2 preceding siblings ...) 1997-04-28 0:00 ` Robert Dewar @ 1997-04-28 0:00 ` Robert Dewar 3 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-28 0:00 UTC (permalink / raw) <<> If I redefine "<" on a scalar type, should "<" on an array-of-that-type > call it? Yes.>> I really think this is also overkill. The fact of the matter is that the only reason we have < on arrays is because strings are arrays of character and we need < on strings. I have never seen < used on any other array type except in ACVC tests... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Matthew Heaney 1997-04-23 0:00 ` Mats Weber @ 1997-04-24 0:00 ` Robert Dewar 1 sibling, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-24 0:00 UTC (permalink / raw) Matthew Heaney says <<Composability should always be guaranteed by user-defined types, too>> Well it is always easy to have straightforward opinions like this when you first look at a problem. But this particular problem is involved, and if you have such a clear cut opinion, you probably have not studied all aspects of the problem. Bob Duff gave a hint of some of the problems! ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Mats Weber 1997-04-22 0:00 ` Robert A Duff @ 1997-04-22 0:00 ` Matthew Heaney 1997-04-23 0:00 ` Mats Weber 1997-04-24 0:00 ` Robert Dewar 2 siblings, 1 reply; 114+ messages in thread From: Matthew Heaney @ 1997-04-22 0:00 UTC (permalink / raw) In article <335CAEFE.35DC@elca-matrix.ch>, Mats.Weber@elca-matrix.ch wrote: >> It took me a while to realize that, yes, even for types (without access >> objects) that have a physical length greater than the logical length, you >> can make the predefined equality work. This is true even for Ada 83, so >> you may be able to apply this technique to your problem. > >Yes, but the performance penalty is pretty big and it's hard to find the >bug if you forget the padding just once. What are you saying? That one should stick with the full-type-tagged technique, and not use the pad-with-extra-characters technique? The performance penalty is nothing compared to the fact that equality doesn't work. What's more important, program correctness or efficiency? > >GNAT 3.09 would fail, I just chacked: there is no padding of strings >shorter than the max length. Making Max_Length a discriminant of a >subcomponent of Bounded_String would solve the problem, probably better >(at least cleaner) than padding with nulls. But of course that solution would have a performance penalty too, right? type Bounded_String is private; private subtype Length_Range is Natural range 0 .. Max_Length; type Bounded_String (Length : Length_Range := 0) is record Buffer : String (1 .. Length); end record; end Bounded_Strings; If I want to append characters to my string, that means I have to change the value of the discriminant, and therefore must use aggregate assignment: procedure Append (Str : String; To : in out Bounded_String) is begin To := (Length => To.Length + Str'Length, Buffer => To.Buffer & Str); end Append; Without the (hidden) discriminant, I can just append the string to what's already there: procedure Append (Str : String; To : in out Bounded_String) is begin To.Buffer (To.Length + 1 .. To.Length + Str'Length) := Str; To.Length := To.Length + Str'Length; end Append; N'est-ce pas? Matt -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Matthew Heaney @ 1997-04-23 0:00 ` Mats Weber 1997-04-23 0:00 ` Robert A Duff 0 siblings, 1 reply; 114+ messages in thread From: Mats Weber @ 1997-04-23 0:00 UTC (permalink / raw) > What are you saying? That one should stick with the full-type-tagged > technique, and not use the pad-with-extra-characters technique? That depends on the overhead of tagged types versus regular records, and on the max length the package is instantiated with. > If I want to append characters to my string, that means I have to change > the value of the discriminant, and therefore must use aggregate assignment: > > [...] > > N'est-ce pas? Sure. Maybe a good optimizer can do something here and detect that the beginning of the string does not change. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-23 0:00 ` Mats Weber @ 1997-04-23 0:00 ` Robert A Duff 1997-04-25 0:00 ` Kevin Cline 0 siblings, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-04-23 0:00 UTC (permalink / raw) In article <335E0A26.16D0@elca-matrix.ch>, Mats Weber <Mats.Weber@elca-matrix.ch> wrote: >Sure. Maybe a good optimizer can do something here and detect that the >beginning of the string does not change. I'd like to see a compiler do that, but I've never seen one do it. Do any? I mean, to append a single character to this array, I just want to increment the discrim, and stick the character in the array. But Ada rules require me to do an assignment on the whole thing. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-23 0:00 ` Robert A Duff @ 1997-04-25 0:00 ` Kevin Cline 1997-04-25 0:00 ` Robert A Duff ` (2 more replies) 0 siblings, 3 replies; 114+ messages in thread From: Kevin Cline @ 1997-04-25 0:00 UTC (permalink / raw) bobduff@world.std.com (Robert A Duff) wrote: >I mean, to append a single character to this array, I just want to >increment the discrim, and stick the character in the array. But Ada >rules require me to do an assignment on the whole thing. Another outstanding reason why Ada never became popular for desktop applications. String manipulation with the Ada standard string types is a major pain in the butt, and amazingly inefficient. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Kevin Cline @ 1997-04-25 0:00 ` Robert A Duff 1997-04-25 0:00 ` Matthew Heaney 1997-04-26 0:00 ` Robert Dewar 2 siblings, 0 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-25 0:00 UTC (permalink / raw) In article <33692089.5794807@news.airmail.net>, Kevin Cline <clines@delete_this.airmail.net> wrote: >Another outstanding reason why Ada never became popular for desktop >applications. String manipulation with the Ada standard string types is a >major pain in the butt, and amazingly inefficient. I'll agree that string manipulation (using Standard.String) is sometimes a pain in the butt. But I don't see how this contributes to the alleged demise of Ada, since the main competitor during the mid-80's (C) is even worse. Nul-terminated strings are much more of a pain in the butt (e.g. debugging the case where you forget the nul, and overwrite random storage). And they're less efficient in many cases. (E.g. suppose I want to allocate a string on the heap, and assign it the value of X concatenated with Y. With nul-term strings, I have to search down the strings twice -- once to find their lengths, whereas with Ada strings, the length is determined in constant time.) - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Kevin Cline 1997-04-25 0:00 ` Robert A Duff @ 1997-04-25 0:00 ` Matthew Heaney 1997-04-25 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Robert Dewar 2 siblings, 2 replies; 114+ messages in thread From: Matthew Heaney @ 1997-04-25 0:00 UTC (permalink / raw) In article <33692089.5794807@news.airmail.net>, clines@delete_this.airmail.net (Kevin Cline) wrote: >>I mean, to append a single character to this array, I just want to >>increment the discrim, and stick the character in the array. But Ada >>rules require me to do an assignment on the whole thing. > >Another outstanding reason why Ada never became popular for desktop >applications. String manipulation with the Ada standard string types is a >major pain in the butt, and amazingly inefficient. This is a specious argument. The design of Ada's String type was chosen precisely because it was *more* efficient than the heap-based approach in other languages. I will tell you why programmers think Ada's string manipulation is a major pain. Many programmers don't know how to store the result of a function that returns an unconstrained string in Ada 83. Given this: function F (...) return String; Programmers innocently tried to do this: declare S : String := F (...); begin Incredibly, that's illegal in Ada 83. All that was required, though, was a simple repair: declare S : constant String := F (...); begin And it's incredible that many Ada programmers didn't know this. Many believe that the value of a constant object must be determined at compile time, so never declare constant objects. They "solved" their problem by never returning unconstrained strings from functions (some shops actually ban functions like that, making vague claims about efficiency), instead opting to always return a constrained, string buffer type (package CMN_String is...). Of course, that has the attendant problem of not being able to override the equality operator, so they either solve that by an Is_Equal method (that no one remembers to call) or making the string buffer limited (now _that's_ a real pain). Another idiom that few Ada programmer's know about is how to declare a mutable string object, or a ragged string array, or a queue of strings: declare S : <mutable string type>; begin S := "hello"; S := "goodbye"; or declare SA : <mutable string array type> := ("hello", "goodbye"); or declare The_Stack : <stack of varying length strings>; begin Push ("hello", On => The_Stack); Push ("goodbye", On => The_Stack); Many attempt to "solve" this problem by manipulating string pointers, and putting varying length string objects on the heap. This is a perennial source of memory leaks, and manual reclamation of memory _is_ a pain (by design). But no heap is required: subtype Length_Range is Natural range 0 .. 132; type String_Buffer (Length : Length_Range := 0) is record Buffer : String (1 .. Length); end record; function "+" (Right : String) return String_Buffer is begin return (Right'Length, Right); end; O : String_Buffer_Array := (+"hello", +"goodbye"); Of course, there is a small problem with the String_Buffer declaration. Given this: procedure P (S : String) is The_Buffer : String_Buffer := +S; begin then declare O : String (2 .. 10); begin P (O); would raise Constraint_Error! Reason: the indices of object S didn't match the index constraints of type String_Buffer. But that's easy enough to solve: function "+" (Right : String) return String_Buffer is subtype Slided is String (1 .. Right'Length); begin return (Right'Length, Slided (Right)); end; procedure P (S : String) is The_Buffer : String_Buffer := +S; begin and then all is well. I could go on about concatenation of constrained strings also raising Constraint_Error (index constraints again), but I won't belabor the point. The other issue is that there wasn't a standard string manipulation library to perform white-space removal, left or right justification, that sort of thing. But all of these very real problems were cleaned up in Ada 95. So you are correct that string manipulation - in Ada 83 - can be a pain, but this is NOT the case for Ada 95, nor are "Ada strings" somehow more inefficient. Matt -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Matthew Heaney @ 1997-04-25 0:00 ` Robert A Duff 1997-04-25 0:00 ` Jon S Anthony 1997-04-26 0:00 ` Robert Dewar 1 sibling, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-04-25 0:00 UTC (permalink / raw) In article <mheaney-ya023680002504970023550001@news.ni.net>, Matthew Heaney <mheaney@ni.net> wrote: >But no heap is required: > > subtype Length_Range is Natural range 0 .. 132; > type String_Buffer (Length : Length_Range := 0) is > record > Buffer : String (1 .. Length); > end record; This is a recipe for disaster, IMHO. You'll end up with programs that work fine most of the time, but fail when they happen to trip over a file name longer than 132 characters (or a line in a file, or whatever it is you're using those strings for). Furthermore, it's not particularly efficient to copy around 132 characters all the time, when most of your strings are around 10 characters long. No, the heap is the right solution to true varying-length strings. Unfortunately, Ada 83 doesn't give you the tools needed to avoid storage leaks without breaking the abstraction. The tool needed is either garbage collection, or finalization and user-defined assignment. >But all of these very real problems were cleaned up in Ada 95. So you are >correct that string manipulation - in Ada 83 - can be a pain, but this is >NOT the case for Ada 95, nor are "Ada strings" somehow more inefficient. "More inefficient" than what? Than C's nul-terminated strings? Perhaps true, at least in many cases. But Ada strings *are* more inefficient than they *could* be. In particular, there's no way to fix the lower bound to 1, so the generated code has to carry around 8 bytes of dope, where 4 would suffice. And do a subtract to determine the length. Or carry 12 bytes, to avoid the subtract. Don't tell me to use a discriminated record, because then I lose all kinds of nice notations (like indexing, slicing, and string literals). - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Robert A Duff @ 1997-04-25 0:00 ` Jon S Anthony 1997-04-27 0:00 ` Robert Dewar 1997-04-28 0:00 ` Robert I. Eachus 0 siblings, 2 replies; 114+ messages in thread From: Jon S Anthony @ 1997-04-25 0:00 UTC (permalink / raw) In article <E975C3.7FK@world.std.com> bobduff@world.std.com (Robert A Duff) writes: > No, the heap is the right solution to true varying-length strings. > Unfortunately, Ada 83 doesn't give you the tools needed to avoid storage > leaks without breaking the abstraction. The tool needed is either > garbage collection, or finalization and user-defined assignment. I strongly agree with this. Of course (as you all know by now) I would go further and say that GC is really the only good solution here. Even if it were only for strings. Finalization and user defined assignment are typically going to be rather more expensive. > "More inefficient" than what? Than C's nul-terminated strings? Perhaps > true, at least in many cases. But Ada strings *are* more inefficient > than they *could* be. In particular, there's no way to fix the lower > bound to 1, so the generated code has to carry around 8 bytes of dope, > where 4 would suffice. And do a subtract to determine the length. Or > carry 12 bytes, to avoid the subtract. Don't tell me to use a > discriminated record, because then I lose all kinds of nice notations > (like indexing, slicing, and string literals). Sad, but true... /Jon -- Jon Anthony Organon Motives, Inc. Belmont, MA 02178 617.484.3383 jsa@organon.com ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Jon S Anthony @ 1997-04-27 0:00 ` Robert Dewar 1997-04-28 0:00 ` Robert I. Eachus 1 sibling, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-27 0:00 UTC (permalink / raw) <<I strongly agree with this. Of course (as you all know by now) I would go further and say that GC is really the only good solution here. Even if it were only for strings. Finalization and user defined assignment are typically going to be rather more expensive.>> That's certainly true, but there are distributed costs for GC, (e.g. restrictions on what pragma Interface can do), so there is a balance here. One of the reasons that Java can more easily introduce GC is that it is a much more closed environment than Ada or C++ (just wait till people start mixing Java and C with the interfacing capability, wild pointers are a menace in C, but they really get to be fun when they mess up the GC structures, and show up as mysterious malfunctions after a few garbage collections :-) So there is a trade off here. What I think would be a nice compromise is to have a storage pool specially for unbounded strings (or similar gizmos) where you got GC in that storage pool -- something to keep looking at ... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Jon S Anthony 1997-04-27 0:00 ` Robert Dewar @ 1997-04-28 0:00 ` Robert I. Eachus 1997-04-29 0:00 ` Jon S Anthony 1 sibling, 1 reply; 114+ messages in thread From: Robert I. Eachus @ 1997-04-28 0:00 UTC (permalink / raw) In article <JSA.97Apr25145343@alexandria> jsa@alexandria (Jon S Anthony) writes: > I strongly agree with this. Of course (as you all know by now) I > would go further and say that GC is really the only good solution > here. Even if it were only for strings. Finalization and user > defined assignment are typically going to be rather more expensive. The cost of finalization and user defined assignment are implementation concerns. But in what sense is Ada.Strings.Unbounded not exactly the "Even if it were only for strings," functionality? Robert Dewar said: > What I think would be a nice compromise is to have a storage pool > specially for unbounded strings (or similar gizmos) where you got > GC in that storage pool -- something to keep looking at ... This is definitely an area where the language can and should evolve. Ada.Strings.Unbounded is a nice package to have, but a generic which exported a Garbage_Collected type would be even more useful in places: generic type Data(<>) is private; type Reference is access all Data; package Garbage_Collected is type Collected is private; function Create(Contents: in Data) return Collected; function Get_Ref(Item: in Collected) return Reference; function Contents(Item: in Collected) return Data; private -- implementation defined end Garbage_Collected; If done right, Get_Ref would probably be a type conversion... -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-28 0:00 ` Robert I. Eachus @ 1997-04-29 0:00 ` Jon S Anthony 0 siblings, 0 replies; 114+ messages in thread From: Jon S Anthony @ 1997-04-29 0:00 UTC (permalink / raw) In article <EACHUS.97Apr28160739@spectre.mitre.org> eachus@spectre.mitre.org (Robert I. Eachus) writes: > > I strongly agree with this. Of course (as you all know by now) I > > would go further and say that GC is really the only good solution > > here. Even if it were only for strings. Finalization and user > > defined assignment are typically going to be rather more expensive. > > The cost of finalization and user defined assignment are > implementation concerns. But in what sense is Ada.Strings.Unbounded > not exactly the "Even if it were only for strings," functionality? Oh, I meant that to apply to GC, as in the only place where GC was actually used. I agree that F/UDA are impl. concerns, but those are still valid concerns. The best that F/UDA can do here is RC and RC is inherently more expensive than tracing style GCs. Even if you avail yourself things such as "non recursive freeing" and deferred counting techniques. > Robert Dewar said: > > > What I think would be a nice compromise is to have a storage pool > > specially for unbounded strings (or similar gizmos) where you got > > GC in that storage pool -- something to keep looking at ... This is definitely something to pursue. What is more, I think you can generalize this notion. I'm working on this sort of thing right now. > This is definitely an area where the language can and should > evolve. Ada.Strings.Unbounded is a nice package to have, but a > generic which exported a Garbage_Collected type would be even more > useful in places: Absolutely. I am working on a whole set of these (related in subsystem hierarchies) which will offer wide ranges of GC options. While you can't do this completely transparently *within* the language (i.e., without compiler support), it is surprising how close you can in fact get. What is more, it is very efficient and very flexible. > generic > type Data(<>) is private; > type Reference is access all Data; > package Garbage_Collected is > > type Collected is private; > > function Create(Contents: in Data) return Collected; > > function Get_Ref(Item: in Collected) return Reference; > > function Contents(Item: in Collected) return Data; > If done right, Get_Ref would probably be a type conversion... In some cases that is exactly correct. In particular, when the collector will work across a class of types this is the most natural approach. Collected needs to be limited as well (OTOH, with proper compiler support that could be relaxed). /Jon -- Jon Anthony Organon Motives, Inc. Belmont, MA 02178 617.484.3383 jsa@organon.com ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Matthew Heaney 1997-04-25 0:00 ` Robert A Duff @ 1997-04-26 0:00 ` Robert Dewar 1997-04-27 0:00 ` Matthew Heaney 1 sibling, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) Matthew Heaney said <<Programmers innocently tried to do this: declare S : String := F (...); begin Incredibly, that's illegal in Ada 83. All that was required, though, was a simple repair:>> As usual, if you think something is incredible, it is probably because you did not carefully study the arguments on both sides. The reason that the above construct is illegal in Ada 83 is that it is potentially confusing, since once you are allowed to make such a declaration to a *variable* as opposed to a *constant*, then it sure looks as though you should be able to assign new string values to S, which is correct, and, in a *very* small step, it sure looks to people like you should be able to assign a different sized string. I often find Ada 95 programmers confused over this, and in particular you see something like: S : String := ""; with the intention of assigning variable length values later, and the Constraint_Error comes as a surprise. Note that if you try S : String; you get from GNAT: s.adb:1:23: unconstrained subtype not allowed (need initialization) which seems like a correct message, but does not solve this confusion. Yes, after some discussion in Ada 95, we decided that the balance between utility and confusion should be reevaluated, and put in this confusing feature (which we know is confusing) because the utility is perceived in retrospect as being worth it. Was this a good idea? I am not sure ... I certainly see it causing a lot of confusion. As to your comments about Ada programmers not understanding runtime computed constants, surely not? Well I guess people can have all kinds of misinformation, but it is a critical feature of Ada that you can declare such constants, and indeed a criticism of much Ada code that I see is that it unnecessarily uses variables, where constants would be preferable. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar @ 1997-04-27 0:00 ` Matthew Heaney 1997-04-27 0:00 ` Robert A Duff 0 siblings, 1 reply; 114+ messages in thread From: Matthew Heaney @ 1997-04-27 0:00 UTC (permalink / raw) In article <dewar.862105379@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: ><<Programmers innocently tried to do this: > >declare > S : String := F (...); >begin > >Incredibly, that's illegal in Ada 83. All that was required, though, was a >simple repair:>> > > >As usual, if you think something is incredible, it is probably because you >did not carefully study the arguments on both sides. > >The reason that the above construct is illegal in Ada 83 is that it is >potentially confusing, since once you are allowed to make such a declaration >to a *variable* as opposed to a *constant*, then it sure looks as though >you should be able to assign new string values to S, which is correct, >and, in a *very* small step, it sure looks to people like you should be able >to assign a different sized string. But people need to be taught that there are o static strings - whose length is fixed, and determined statically (eg Pascal) o dynamic strings - the length of string objects are fixed, but are determined dynamically (eg Ada) o flexible strings - the length of string objects can change (Algol 68) So let's just tell new Ada programmers that Ada has dynamic strings. I find that it helps to think of the analogy between discriminated records and strings, ie the constraint is determined by the initial value. >As to your comments about Ada programmers not understanding runtime >computed constants, surely not? Well I guess people can have all kinds >of misinformation, but it is a critical feature of Ada that you can >declare such constants, and indeed a criticism of much Ada code that I >see is that it unnecessarily uses variables, where constants would be >preferable. I have had a similar experience. I always have to remind programmers to declare constants instead of variables. I've been studying programming language theory of late, and have been learning about functional programming, and the difference between binding and assignment. Interestingly - perhaps you can shed some light on the history - Ada chooses assignment when binding would seem to do. For example: declare O : constant T := <T expression>; begin This declares a constant object, using assignment. But why? Couldn't one bind O to a value, w/o using assignment, similar to a LISP let expression? Something like: declare O : constant T'(<T expression>); begin or declare O : T is <T expression>; begin The binding operator in Ada is "is" (I'm on very thin ice here). For example, I statically bind an identifier to a subprogram value: function F return T is <function body expression>; Now the reason this is interesting to me, is that it means I could give limited objects a value during their elaboration, without breaking any rule that says assigment isn't available for limited types. I just seems to me that object declaration should _bind_ a value to an object; it shouldn't have anything to do with _assignment_, which I interpret to mean "move a value into a certain memory cell." That whole von Neumann thing. The repercussion of the Ada design is that limited types must be definate, and that the programmer can't choose the initial value for his limited object (during its elaboration). Here's an example of something I wanted to, but couldn't, because of this problem, um, I mean "issue." Without using heap, I want a data structure to export a factory method that returns an iterator appropriate for iterating over that data structure. The iterator needs to be limited, because I'd like to have an access discriminant that designates the data structure. Sort of like: type Root_Stack is abstract tagged private; type Root_Stack_Iterator (Stack : access Root_Stack'Class) is abstract tagged limited private; function Iterator (Stack : Root_Stack) return Root_Stack_Iterator'Class; procedure Proc (Stack : in out Root_Stack'Class) is The_Iterator : Stack_Iterator'Class (Stack'Access) := Iterator (Stack); -- not legal Ada begin or something like that. The idea is to have a class-wide object on the stack, and for that class-wide object to be limited. But I can't do that, because I need to give the class-wide object a default value (because it's indefinate), but can't because assignment isn't available. Right now, the factory method must return a pointer to an iterator on the heap: function New_Iterator (Stack : access Root_Stack) return Stack_Iterator_Access; declare The_Stack : aliased Bounded_Stack; The_Iterator : Stack_Iterator_Access := New_Iterator (The_Stack'Access); begin Why should there be any difference between an unconstrained object (a class-wide iterator) on the stack or on the heap? Yet I can do one, and not the other. There's something a bit odd about "initialization during elaboration" meaning the same thing as "assignment," but I'm not learned enough yet to be able to say why. Perhaps someone out there in cyberland can explain it to me. Oh, well, I'm just thinking out load. I really like Ada, you know. Matt -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-27 0:00 ` Matthew Heaney @ 1997-04-27 0:00 ` Robert A Duff 0 siblings, 0 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-27 0:00 UTC (permalink / raw) In article <mheaney-ya023680002704970206040001@news.ni.net>, Matthew Heaney <mheaney@ni.net> wrote: >But people need to be taught that there are >o static strings - whose length is fixed, and determined statically (eg Pascal) >o dynamic strings - the length of string objects are fixed, but are >determined dynamically (eg Ada) >o flexible strings - the length of string objects can change (Algol 68) I always thought "dynamic" meant what you call "flexible". Too bad the software industry doesn't agree on terminology very well. >I have had a similar experience. I always have to remind programmers to >declare constants instead of variables. IMHO, a better language design would be to make objects constant by default, and stick in an extra keyword when you want variable. Ada does it the other way 'round. How about a compiler warning for variables that could have been constants? >This declares a constant object, using assignment. But why? Couldn't one >bind O to a value, w/o using assignment, similar to a LISP let expression? Yeah, I've done some thinking about that, and I suspect something along these lines would make a lot of sense. > The_Iterator : Stack_Iterator'Class (Stack'Access) := > Iterator (Stack); -- not legal Ada I'm not sure why you want to mention Stack twice. Why not have the initialization code for your iterator type do the necessary stuff (and not use a class-wide iterator)? Would that work? Note also that Ada 95 allows: X: T renames F(...); even if T is a limited type. X is constant here, though. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Kevin Cline 1997-04-25 0:00 ` Robert A Duff 1997-04-25 0:00 ` Matthew Heaney @ 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney 2 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) Kevin Cline said <<>I mean, to append a single character to this array, I just want to >increment the discrim, and stick the character in the array. But Ada >rules require me to do an assignment on the whole thing. Another outstanding reason why Ada never became popular for desktop applications. String manipulation with the Ada standard string types is a major pain in the butt, and amazingly inefficient.>> That seems completely specious reasoning. Just because one approach that one might use for string manipulation is not permitted for very good reasons do not mean that "string manipulation with the Ada standard string types is a major pain in the butt", or that it is "amazingly inefficient". It is perfectly possible to write convenient, efficient string processing code in Ada, and many people have done it. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar @ 1997-04-26 0:00 ` Matthew Heaney 0 siblings, 0 replies; 114+ messages in thread From: Matthew Heaney @ 1997-04-26 0:00 UTC (permalink / raw) In article <dewar.862096820@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: ><<>I mean, to append a single character to this array, I just want to >>increment the discrim, and stick the character in the array. But Ada >>rules require me to do an assignment on the whole thing. > >Another outstanding reason why Ada never became popular for desktop >applications. String manipulation with the Ada standard string types is a >major pain in the butt, and amazingly inefficient.>> > >That seems completely specious reasoning. Furthermore, that example had nothing to do with type String, really. The discussion was about efficiently implementing a bounded buffer; it could have been any (non-limited) type, not just character arrays. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Mats Weber 1997-04-22 0:00 ` Robert A Duff 1997-04-22 0:00 ` Matthew Heaney @ 1997-04-24 0:00 ` Robert Dewar 1997-04-24 0:00 ` Robert A Duff 2 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-24 0:00 UTC (permalink / raw) <<> You the purchaser of a compiler should test to make sure Bounded_String > works. If the predefined equality is ever getting called, let your vendor > know his product is broken. Perhaps this should be an ACVC test, too > (maybe it is already).>> Is this right, I do not know of an AI that has been issued that requires equality to compose on the Bounded_String type. Bob (Duff) isn't that right -- we discussed it, but made no final decision as I remember. GANT's behavior may note be what people want here, but I don't want to change it, and encourage people to write incorrect code that assumes that equality on bounded strings does compose, unless there is an AI that requires this. If there is an AI, please let me know (memory is not always trusty here :-) ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Robert Dewar @ 1997-04-24 0:00 ` Robert A Duff 1997-04-25 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-04-24 0:00 UTC (permalink / raw) In article <dewar.861864029@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: >Is this right, I do not know of an AI that has been issued that requires >equality to compose on the Bounded_String type. Bob (Duff) isn't that >right -- we discussed it, but made no final decision as I remember. There is an AI, and I posted it in another note. The ARG made a "final" decision, but WG9 has not yet voted on it. My memory is that we discussed it at the Vermont meeting last Fall (I believe you were there, since you hosted the meeting ;-) ) and the entire ARG agreed unanimously that "=" should compose properly for all predefined types except System.Address. For System.Address, all but one ARG member agreed that "=" should compose -- I was the "one", and I argued that Address semantics are by their nature implementation dependent, so we shouldn't say anything about it. I was outvoted on that point. So, yes, you ought to change Bounded_String to be tagged, or else use some special hack. Unless of course you think WG9 will disapprove the AI -- I doubt it. I also remember you saying that such special hacks are easy to implement in GNAT, so you could save one word per Bounded_String, if you like. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-24 0:00 ` Robert A Duff @ 1997-04-25 0:00 ` Robert Dewar 1997-04-25 0:00 ` Matthew Heaney 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-25 0:00 UTC (permalink / raw) Bob said <<So, yes, you ought to change Bounded_String to be tagged, or else use some special hack. Unless of course you think WG9 will disapprove the AI -- I doubt it. I also remember you saying that such special hacks are easy to implement in GNAT, so you could save one word per Bounded_String, if you like.>> That's right, I remember now. I had remembered the discussion about unbounded strings, but forgot that we decided to extend it. In fact avoiding the use of tagged types is much more than saving one word, it saves dragging in all the tagged support stuff if you are not otherwise using tagged types. I think probably the nicest way of doing this is to introduce a pragma pragma Compose_Equality (type-name); yes, it's a bit aggressive, but then so is the ARG's decision, and if the problem in the standard library is important enough to be worth the ARG changing the language, it seems reasonable to spupose that other libraries will need the same treatment. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Robert Dewar @ 1997-04-25 0:00 ` Matthew Heaney 1997-04-26 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Matthew Heaney @ 1997-04-25 0:00 UTC (permalink / raw) In article <dewar.861970467@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: >I think probably the nicest way of doing this is to introduce a pragma > >pragma Compose_Equality (type-name); > >yes, it's a bit aggressive, but then so is the ARG's decision, and if the >problem in the standard library is important enough to be worth the ARG >changing the language, it seems reasonable to spupose that other libraries >will need the same treatment. I don't think anyone's arguing for a language change (though you all know by now I didn't agree with the decision). All I'm saying is to mandate a sort of coding convention that says, implement your abstraction so that equality always works, even predefined equality for when it inevitably re-emerges. Can the programmer assume Bounded_String composes, or not? The RM95 just needs to state - unambigously - whether it does or doesn't. Whatever way the ARG decides (they did, for the former), it doesn't require a change to the language. Right now, the RM95 is silent about whether equality composes for Bounded_String. The requirement for composability is therefore ambiguous, which isn't acceptable for any kind of requirements document. Matt P.S. By the way, it would be really swell if compilers could issue an informational diagnostic when predefined operators re-emerge for a type. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-25 0:00 ` Matthew Heaney @ 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Robert A Duff 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) <<Right now, the RM95 is silent about whether equality composes for Bounded_String. The requirement for composability is therefore ambiguous, which isn't acceptable for any kind of requirements document.>> The RM leaves many aspects of Ada as implementation defined. There is no general principle that this is unacceptable. Indeed, trying to remove all implementation dependencies as Java does is an efficiency disaster -- for example in the Java case, the requirement for IEEE fpt leads to completely unaceptable performance on some targets (such as SGI and Alpha), but in practice no one takes these specs that seriously. In the Ada world, we prefer to have the spec taken seriously, and explicitily recognize the implementation dependencies. So there is no general principle here, other than the general one which says don't make things impl-dependent unless there is a good reason. So the question is whether there is a good reason here. Obviously the ARG on reflection feels that it is better that this not be impl dependent, but there is a cost -- in the case of bounded string, either there will be a non-zero efficiency cost at runtime for ALL operatoins on bounded strings ALL the time, or you need a very special non-Ada kludge in the compiler -- and we don't like to require these. I note that very often people assume that because the GNAT library is written in Ada 95, it can be used with any Ada 95 compiler. In particular for instance, I often meet people who have been told by sales people for other compilers not to worry about the informatoin systems annex, since you can just use the GNAT libraries. Well this of course is NOT always true, and in particular is not true at all of the informatoin systems annex stuff (since this requires fundamentall support from the compiler for high precision deciaml fixed point which at present only exists in GNAT, and also recognition of some intrinsics (e.g. the one for DIVIDE). Well up to now the bounded string implementation has indeed been portable (I know for example that Aonix has distributed GNAT sources for some of the library functions for Object Ada, which is perfectly fine, although they tend necessarily to be out of date versions -- I don't know if bounded string is such a package). Now with the version of GNAT in which this problem is "fixed", you will have to add bounded strings to the list of GNAT packages that are GNAT specific. No big deal, and certainly not a disadvantage for us, but something we like to avoid where possible. Robert Dewar Ada Core Technologis ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar @ 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Robert Dewar 0 siblings, 2 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-26 0:00 UTC (permalink / raw) In article <dewar.862054383@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: ><<Right now, the RM95 is silent about whether equality composes for >Bounded_String. The requirement for composability is therefore ambiguous, >which isn't acceptable for any kind of requirements document.>> > >The RM leaves many aspects of Ada as implementation defined. There is no >general principle that this is unacceptable. Robert, I think you misunderstand his point. I think he's saying that if so-and-so is implementation dependent, the RM should say, "so-and-so is implementation dependent", rather than being silent on the issue. I agree with that. Otherwise, you're never quite sure whether the language designers meant it to be undefined, versus they never thought about it. In this particular case, I think the language designers never thought about whether "=" should compose for various predefined types, such as Bounded_String, so its implementation-dependence is accidental. In general, this principle is good, and I tried to obey it in RM95 -- if something is undefined, then the RM should say so explicitly. Nothing should be undefined just because the RM doesn't bother to define it. Anyway, this is why we have an AI on this point. >... Indeed, trying to remove all >implementation dependencies as Java does is an efficiency disaster -- for >example in the Java case, the requirement for IEEE fpt leads to completely >unaceptable performance on some targets (such as SGI and Alpha), but >in practice no one takes these specs that seriously. Perhaps Java goes too far. IMHO Ada doesn't go far enough in this direction. There's always a trade-off between nailing down the semantics, versus efficiency. The IEEE example is rather extreme (hardware floating point is almost right, but you have to do floating point in software to get it just right). Of course, Ada and Java are targetting rather different application areas. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert A Duff @ 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney 1997-04-27 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1 sibling, 2 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) Bob Duff said <<Robert, I think you misunderstand his point. I think he's saying that if so-and-so is implementation dependent, the RM should say, "so-and-so is implementation dependent", rather than being silent on the issue. I agree with that. Otherwise, you're never quite sure whether the language designers meant it to be undefined, versus they never thought about it. In this particular case, I think the language designers never thought about whether "=" should compose for various predefined types, such as Bounded_String, so its implementation-dependence is accidental. In general, this principle is good, and I tried to obey it in RM95 -- if something is undefined, then the RM should say so explicitly. Nothing should be undefined just because the RM doesn't bother to define it. Anyway, this is why we have an AI on this point.>> I do not disagree that it is a good idea to pin down this particular lack of specification, but I strongly disagree with the general principle here. The idea of a package spec in Ada 83 or Ada 95 is that you are free to implement the body anyway you like, and of course there are things that are left open. FOr example, the paragraph above would require us to say things like: a) it is implementation defined what the value of x'size is for the following types (Address, Unbounded_String, ...) b) It is implementation defined whether it is possible to apply pragma Pack to arrays of types .... c) It is implementation defined what values of component size are permitted for arrays of types ... etc. If you think these all need to be made explicit, get busy, you have a lot of AI's to write! ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar @ 1997-04-26 0:00 ` Matthew Heaney 1997-04-27 0:00 ` Robert Dewar 1997-04-27 0:00 ` Robert A Duff 1 sibling, 1 reply; 114+ messages in thread From: Matthew Heaney @ 1997-04-26 0:00 UTC (permalink / raw) In article <dewar.862097010@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: >In general, this principle is good, and I tried to obey it in RM95 -- if >something is undefined, then the RM should say so explicitly. Nothing >should be undefined just because the RM doesn't bother to define it. > >Anyway, this is why we have an AI on this point.>> Robert said: >I do not disagree that it is a good idea to pin down this particular >lack of specification, but I strongly disagree with the general principle >here. The idea of a package spec in Ada 83 or Ada 95 is that you are >free to implement the body anyway you like, and of course there are things >that are left open. FOr example, the paragraph above would require us to >say things like: > >a) it is implementation defined what the value of x'size is for the following >types (Address, Unbounded_String, ...) [pedantry snipped :-)] Robert, you're being a wee bit pedantic, don't you think? We simply need to specify the _external_ behavior of type Bounded_String, specifically the behavior of equality, under _all_ circumstances, including those times when predefined operators re-emerge. No one is suggesting we publically specify the any aspects of the _representation_ of Bounded_String. Perhaps the real issue is, What does "representation" mean? You assume equality is a representation issue, others assume equality is not a representation issue (ie is external behavior). So let's resolve _that_ ambiguity. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Matthew Heaney @ 1997-04-27 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-27 0:00 UTC (permalink / raw) Matthew said <<Robert, you're being a wee bit pedantic, don't you think? We simply need to specify the _external_ behavior of type Bounded_String, specifically the behavior of equality, under _all_ circumstances, including those times when predefined operators re-emerge. No one is suggesting we publically specify the any aspects of the _representation_ of Bounded_String. Perhaps the real issue is, What does "representation" mean? You assume equality is a representation issue, others assume equality is not a representation issue (ie is external behavior). So let's resolve _that_ ambiguity >> Well first of all, the exhortation to resolve that ambiguity is like a coach arriving half an hour after his team has won the championship, and exhorting them to win -- this *particular* issue is already decided by an extension to the language. I do not at all "assume that equality is a reprsentatoin issue", what makes you think this? I was reacting to your general claim that it is necessary that the RM specify all aspects of the interface for the annex A packages. You seemed to be arguing: "we must specify the behavior of equality, because we must specify all such behavior" If I misread you, then my comment does not apply. The point is that the RM as it stands leaves it implementation dependent whether or not bounded string equality applies. There are lots of other things it leaves impl dependent. The mere fact that something is left impl dependent is not of itself bad. In a particular instance, it may be a mistake, and, as you see, the ARG is in the business of addressing specific mistakes. I do not argue that equality for bounded string should be left impl dependent (if you check the minutes of the Maple Syrup meeting of the ARG, you will find that I voted for this AI :-) ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney @ 1997-04-27 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1 sibling, 1 reply; 114+ messages in thread From: Robert A Duff @ 1997-04-27 0:00 UTC (permalink / raw) In article <dewar.862097010@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: >I do not disagree that it is a good idea to pin down this particular >lack of specification, but I strongly disagree with the general principle >here. The idea of a package spec in Ada 83 or Ada 95 is that you are >free to implement the body anyway you like, and of course there are things >that are left open. FOr example, the paragraph above would require us to >say things like: > >a) it is implementation defined what the value of x'size is for the following >types (Address, Unbounded_String, ...) > >b) It is implementation defined whether it is possible to apply pragma Pack >to arrays of types .... > >c) It is implementation defined what values of component size are permitted >for arrays of types ... All examples from chap 13. Hmm. It's always hard to pin things down in that area. But in fact we *do* say all of the above, and more, a bit more concisely, in 13.1(20), which gives implementations permission to pretty much anything the like, and then we give specific exceptions to that permission (like packing an array of "0..3" has to do something good, whereas packing an array of "access Integer" we don't require much). (Actually "implementation defined" is incorrect above, since that's explicitly defined to mean "the implementer must document it". But that's a minor distinction, IMHO.) Anyway, let's talk about the higher-level features of the language, namely chaps 1..12, and skip chap 13 for this argument. At least in chaps 1..12 we have some hope of being precise. There are certain things that are implementation dependent, but if that's the case, we should say so. For example, the following are legitimate statements in a language definition, when talking about the run-time semantics of procedure calls: - The arguments are evaluated in left-to-right order, and then the procedure body is executed. or: - The arguments are evaluated in an arbitrary order, and then the procedure body is executed. But this: - The arguments are evaluated, and then the procedure body is executed. is evil, because it leaves one wondering about the order. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-27 0:00 ` Robert A Duff @ 1997-04-26 0:00 ` Robert Dewar 1997-05-02 0:00 ` Nick Roberts 0 siblings, 1 reply; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) Bob Duff said <<All examples from chap 13. Hmm. It's always hard to pin things down in that area. But in fact we *do* say all of the above, and more, a bit more concisely, in 13.1(20), which gives implementations permission to pretty much anything the like, and then we give specific exceptions to that permission (like packing an array of "0..3" has to do something good, whereas packing an array of "access Integer" we don't require much).>> Let's see what that para says: 20 An implementation may interpret aspects of representation in an implementation-defined manner. An implementation may place implementation- defined restrictions on representation items. A recommended level of support is specified for representation items and related features in each subclause. These recommendations are changed to requirements for implementations that support the Systems Programming Annex (see C.2, ``Required Representation Support''). Nice, but it has nothing at all to do with the issue of predefined types in the annex A packages. Except to say nothing at all about them, which could have also been achieved by saying nothing at all. This para is about rep clauses themselves, not on requirements for Annex A. <<Anyway, let's talk about the higher-level features of the language, namely chaps 1..12, and skip chap 13 for this argument. At least in chaps 1..12 we have some hope of being precise.>> Yes, but that is irrelevant to the discussion, which is about the restrictions placed on bodies in annex A. At least that's what *I* was talking about (remember the subject line, and we are off on thinking about composition of equality). In fact as you know another MAJOR unresolved issue is the status of the annex A packages with respect to distribution. IT seems like that is another big hole! We also have the worrying non-portabiility of System being Pure or Preelaborated, which is another similar issue Are annex A packages allowed to have storage leaks? Where does it say otherwise -- I can think of many other questions like this. ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar @ 1997-05-02 0:00 ` Nick Roberts 1997-05-04 0:00 ` Robert Dewar 0 siblings, 1 reply; 114+ messages in thread From: Nick Roberts @ 1997-05-02 0:00 UTC (permalink / raw) Robert Dewar <dewar@merv.cs.nyu.edu> wrote in article <dewar.862111056@merv>... [...] > > Nice, but it has nothing at all to do with the issue of predefined types > in the annex A packages. Except to say nothing at all about them, which > could have also been achieved by saying nothing at all. This para is > about rep clauses themselves, not on requirements for Annex A. > [...] Have you been reading Lewis Carroll, Robert? Nick ;-) ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-05-02 0:00 ` Nick Roberts @ 1997-05-04 0:00 ` Robert Dewar 0 siblings, 0 replies; 114+ messages in thread From: Robert Dewar @ 1997-05-04 0:00 UTC (permalink / raw) Nick said <<> Nice, but it has nothing at all to do with the issue of predefined types > in the annex A packages. Except to say nothing at all about them, which > could have also been achieved by saying nothing at all. This para is > about rep clauses themselves, not on requirements for Annex A. > [...] Have you been reading Lewis Carroll, Robert?>> Sorry, I do not see why you think the para you quoted has antying to do with the issue at hand, can you explain yourself -- I think you are seriously confused here ... ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar @ 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney 1997-04-27 0:00 ` Robert A Duff 1 sibling, 2 replies; 114+ messages in thread From: Robert Dewar @ 1997-04-26 0:00 UTC (permalink / raw) <<In article <dewar.862054383@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: ><<Right now, the RM95 is silent about whether equality composes for >Bounded_String. The requirement for composability is therefore ambiguous, >which isn't acceptable for any kind of requirements document.>> > >The RM leaves many aspects of Ada as implementation defined. There is no >general principle that this is unacceptable.>> One postscript to my previous comment. It is NOT ambiguous whether there is a requirement for composability of equality for Bounded_String in the RM in the absence of the AI. It is crystal clear that there is no such requirement! The AI is not addressing the ambiguity of the requirement, it is adding a requirement where none existed previously! ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar @ 1997-04-26 0:00 ` Matthew Heaney 1997-04-27 0:00 ` Robert A Duff 1 sibling, 0 replies; 114+ messages in thread From: Matthew Heaney @ 1997-04-26 0:00 UTC (permalink / raw) In article <dewar.862097259@merv>, dewar@merv.cs.nyu.edu (Robert Dewar) wrote: >>The RM leaves many aspects of Ada as implementation defined. There is no >>general principle that this is unacceptable.>> > >One postscript to my previous comment. It is NOT ambiguous whether there >is a requirement for composability of equality for Bounded_String in the >RM in the absence of the AI. It is crystal clear that there is no such >requirement! > >The AI is not addressing the ambiguity of the requirement, it is adding a >requirement where none existed previously! No, no, no. That fact that many programmers wonder whether Bounded_String composes or not is proof that there is an ambiguity. Just tell the programmer what the requirement is, so he doesn't have to guess. And even if the AI did add a requirement, is that so bad? It's not as if this is anything new. In Ada 83, it required an AI to state unambiguously that Boolean'Size is 1. In Ada 95, this became an explicitly stated, unambiguous requirement. No one is asking for a language change per say, just a complete, unambiguous statement about the external behavior of Bounded_String. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney @ 1997-04-27 0:00 ` Robert A Duff 1 sibling, 0 replies; 114+ messages in thread From: Robert A Duff @ 1997-04-27 0:00 UTC (permalink / raw) In article <dewar.862097259@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> wrote: >One postscript to my previous comment. It is NOT ambiguous whether there >is a requirement for composability of equality for Bounded_String in the >RM in the absence of the AI. It is crystal clear that there is no such >requirement! > >The AI is not addressing the ambiguity of the requirement, it is adding a >requirement where none existed previously! Quite true. The RM (without this AI) clearly allows "=" of Bounded_String to compose, or to not compose. - Bob ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-21 0:00 Equality operator overloading in ADA 83 Manuel Wenger 1997-04-22 0:00 ` Matthew Heaney @ 1997-04-22 0:00 ` Kevin Cline 1997-04-22 0:00 ` Mark A Biggar 1997-04-24 0:00 ` Keith Thompson 1997-04-22 0:00 ` Mats Weber 2 siblings, 2 replies; 114+ messages in thread From: Kevin Cline @ 1997-04-22 0:00 UTC (permalink / raw) "Manuel Wenger" <manuel@thunder.ch*> wrote: > >Hi, >I've started doing some DecADA 83 programming at a technical engineering >school ... and I've run into a problem that I was unable to solve (and my >teacher didn't know any better either :-)) > >I've tried to overload the "=" operator for fractions in a package. It >obviously doesn't work if the type isn't defined as "limited private", and >I don't want that. As an alternative, I found out that I might as well do a >renaming declaration, just by defining the type as "private" - so I've >tried doing that as well, and then using the following to rename the equal >sign: > >In other words, how do I tell my "equal" function to be an equality >operator, authorized to be renamed into "="? HELP! :) > You can't. Period. Why? I don't know. Drove me crazy once. Maybe some Ada-83 committee member will volunteer why it was considered reasonable to redefine '<' and '>' but not '=' . ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Kevin Cline @ 1997-04-22 0:00 ` Mark A Biggar 1997-04-24 0:00 ` Keith Thompson 1 sibling, 0 replies; 114+ messages in thread From: Mark A Biggar @ 1997-04-22 0:00 UTC (permalink / raw) In article <33602040.3178674@news.airmail.net> clines@delete_this.airmail.net (Kevin Cline) writes: >"Manuel Wenger" <manuel@thunder.ch*> wrote: >>I've started doing some DecADA 83 programming at a technical engineering >>school ... and I've run into a problem that I was unable to solve (and my >>teacher didn't know any better either :-)) >>I've tried to overload the "=" operator for fractions in a package. It >>obviously doesn't work if the type isn't defined as "limited private", and >>I don't want that. As an alternative, I found out that I might as well do a >>renaming declaration, just by defining the type as "private" - so I've >>tried doing that as well, and then using the following to rename the equal >>sign: >>In other words, how do I tell my "equal" function to be an equality >>operator, authorized to be renamed into "="? HELP! :) >You can't. Period. Why? I don't know. Drove me crazy once. >Maybe some Ada-83 committee member will volunteer why it was >considered reasonable to redefine '<' and '>' but not '=' . Actually you can by cheating and using generics. define a genreics package looking something like: generic type FOO is limited private; with function EQ(L,R: FOO) return Boolean is <>; package MAKE_EQUALS is function "="(L,R: FOO) return Boolean; end MAKE_EQUALS; package body MAKE_EQUALS is function "="(L,R: FOO) return Boolean is body return EQ(L,R); end "='; end MAKE_EQUALS; now you can instantiate it as: package FAKE_IT is new MAKE_EQUALS(FOO => Your_Type, EQ => Your_Equals); Now FAKE_IT."=" is an equality operator of your type and can be freely renamed into what ever scope you want. -- Mark Biggar mab@wdl.lmco.com ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-22 0:00 ` Kevin Cline 1997-04-22 0:00 ` Mark A Biggar @ 1997-04-24 0:00 ` Keith Thompson 1 sibling, 0 replies; 114+ messages in thread From: Keith Thompson @ 1997-04-24 0:00 UTC (permalink / raw) In <33602040.3178674@news.airmail.net> clines@delete_this.airmail.net (Kevin Cline) writes: > "Manuel Wenger" <manuel@thunder.ch*> wrote: [...] > >In other words, how do I tell my "equal" function to be an equality > >operator, authorized to be renamed into "="? HELP! :) > > You can't. Period. Why? I don't know. Drove me crazy once. > Maybe some Ada-83 committee member will volunteer why it was > considered reasonable to redefine '<' and '>' but not '=' . Actually, you can. Though the designers of Ada 83 intended to prohibit overloading of "=" for non-limited types, it can be done by tricky use of generics. I don't remember the exact details, but the idea is that it's legal to overload "=" for a limited private generic formal type and it's legal to pass a non-limited type as the actual for a limited private formal. Perhaps someone else can provide details and credit the originator. -- Keith Thompson (The_Other_Keith) kst@sd.aonix.com <http://www.aonix.com> <*> TeleSo^H^H^H^H^H^H Alsy^H^H^H^H Thomson Softw^H^H^H^H^H^H^H^H^H^H^H^H^H Aonix 5040 Shoreham Place, San Diego, CA, USA, 92122-5989 "Humor is such a subjective thing." -- Cartagia ^ permalink raw reply [flat|nested] 114+ messages in thread
* Re: Equality operator overloading in ADA 83 1997-04-21 0:00 Equality operator overloading in ADA 83 Manuel Wenger 1997-04-22 0:00 ` Matthew Heaney 1997-04-22 0:00 ` Kevin Cline @ 1997-04-22 0:00 ` Mats Weber 2 siblings, 0 replies; 114+ messages in thread From: Mats Weber @ 1997-04-22 0:00 UTC (permalink / raw) > In other words, how do I tell my "equal" function to be an equality > operator, authorized to be renamed into "="? HELP! :) There is a way, but it is contrived (Ada 83 was designed to make it impossible, but a hole was left. Use at your own risk as some compilers may not like it very much, and read the other replies about the reemergence of predefined "="): generic type T is limited private; with function "=" (X, Y : T) return BOOLEAN is <>; package MESS_UP_EQUALITY is package ENCLOSE_EQUALITY is function "=" (X, Y : T) return BOOLEAN renames MESS_UP_EQUALITY."="; end ENCLOSE_EQUALITY; end MESS_UP_EQUALITY; type T is ...; function Equal (L, R : T) return Boolean; package T_Equality is new MESS_UP_EQUALITY(T => T, "=" => Equal); function "=" (L, R : T) return Boolean renames T_Equality.Enclose_Equality."="; ^ permalink raw reply [flat|nested] 114+ messages in thread
end of thread, other threads:[~1997-05-07 0:00 UTC | newest] Thread overview: 114+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1997-04-21 0:00 Equality operator overloading in ADA 83 Manuel Wenger 1997-04-22 0:00 ` Matthew Heaney 1997-04-22 0:00 ` Philip Brashear 1997-04-22 0:00 ` Mats Weber 1997-04-22 0:00 ` Robert A Duff 1997-04-22 0:00 ` Mats Weber 1997-04-22 0:00 ` Matthew Heaney 1997-04-23 0:00 ` Mats Weber 1997-04-23 0:00 ` Robert Dewar 1997-04-24 0:00 ` Robert A Duff 1997-04-29 0:00 ` Mats Weber 1997-05-01 0:00 ` Robert Dewar 1997-04-23 0:00 ` Robert A Duff 1997-04-24 0:00 ` Mats Weber 1997-04-24 0:00 ` Matthew Heaney 1997-04-25 0:00 ` Robert Dewar 1997-04-25 0:00 ` Matthew Heaney 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Fergus Henderson 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-27 0:00 ` Robert Dewar 1997-04-25 0:00 ` Robert Dewar 1997-04-25 0:00 ` Matthew Heaney 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-24 0:00 ` Robert A Duff 1997-04-24 0:00 ` Robert Dewar 1997-04-25 0:00 ` Robert A Duff 1997-04-26 0:00 ` Nick Roberts 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-27 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-28 0:00 ` Simon Wright 1997-04-29 0:00 ` Robert I. Eachus 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney 1997-05-02 0:00 ` Nick Roberts 1997-05-04 0:00 ` Robert Dewar 1997-05-05 0:00 ` Robert A Duff 1997-05-05 0:00 ` Mats Weber 1997-05-05 0:00 ` Robert Dewar 1997-05-06 0:00 ` Matthew Heaney 1997-05-06 0:00 ` Robert Dewar 1997-05-07 0:00 ` Tucker Taft 1997-04-29 0:00 ` Mats Weber 1997-05-01 0:00 ` Robert Dewar [not found] ` <01bc571c$01f3ffc0$5de2b8cd@p5120.bda> 1997-05-03 0:00 ` Robert Dewar 1997-04-27 0:00 ` Robert Dewar 1997-04-27 0:00 ` Fergus Henderson 1997-04-27 0:00 ` Robert Dewar 1997-04-28 0:00 ` Fergus Henderson 1997-04-28 0:00 ` Robert Dewar 1997-04-25 0:00 ` Kevin Cline 1997-04-25 0:00 ` Mats Weber 1997-04-27 0:00 ` Robert Dewar 1997-04-29 0:00 ` Mats Weber 1997-04-25 0:00 ` Mats Weber 1997-04-25 0:00 ` Robert Dewar 1997-04-29 0:00 ` Mats Weber 1997-05-01 0:00 ` Robert Dewar 1997-04-25 0:00 ` Robert A Duff 1997-04-25 0:00 ` Mats Weber 1997-04-27 0:00 ` Geert Bosch 1997-04-28 0:00 ` Robert Dewar 1997-04-29 0:00 ` Mats Weber 1997-04-29 0:00 ` Robert A Duff 1997-04-29 0:00 ` Matthew Heaney 1997-05-02 0:00 ` Tucker Taft 1997-05-02 0:00 ` Robert Dewar 1997-05-02 0:00 ` Robert A Duff 1997-05-03 0:00 ` Robert Dewar 1997-05-01 0:00 ` Robert Dewar 1997-04-29 0:00 ` Matthew Heaney 1997-05-01 0:00 ` Robert Dewar 1997-04-28 0:00 ` Robert Dewar 1997-04-24 0:00 ` Robert Dewar 1997-04-22 0:00 ` Matthew Heaney 1997-04-23 0:00 ` Mats Weber 1997-04-23 0:00 ` Robert A Duff 1997-04-25 0:00 ` Kevin Cline 1997-04-25 0:00 ` Robert A Duff 1997-04-25 0:00 ` Matthew Heaney 1997-04-25 0:00 ` Robert A Duff 1997-04-25 0:00 ` Jon S Anthony 1997-04-27 0:00 ` Robert Dewar 1997-04-28 0:00 ` Robert I. Eachus 1997-04-29 0:00 ` Jon S Anthony 1997-04-26 0:00 ` Robert Dewar 1997-04-27 0:00 ` Matthew Heaney 1997-04-27 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney 1997-04-24 0:00 ` Robert Dewar 1997-04-24 0:00 ` Robert A Duff 1997-04-25 0:00 ` Robert Dewar 1997-04-25 0:00 ` Matthew Heaney 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney 1997-04-27 0:00 ` Robert Dewar 1997-04-27 0:00 ` Robert A Duff 1997-04-26 0:00 ` Robert Dewar 1997-05-02 0:00 ` Nick Roberts 1997-05-04 0:00 ` Robert Dewar 1997-04-26 0:00 ` Robert Dewar 1997-04-26 0:00 ` Matthew Heaney 1997-04-27 0:00 ` Robert A Duff 1997-04-22 0:00 ` Kevin Cline 1997-04-22 0:00 ` Mark A Biggar 1997-04-24 0:00 ` Keith Thompson 1997-04-22 0:00 ` Mats Weber
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox