comp.lang.ada
 help / color / mirror / Atom feed
* Equality operator overloading in ADA 83
@ 1997-04-21  0:00 Manuel Wenger
  1997-04-22  0:00 ` Kevin Cline
                   ` (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-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   ` Mats Weber
  1997-04-22  0:00     ` Matthew Heaney
@ 1997-04-22  0:00     ` Robert A Duff
  1997-04-22  0:00       ` Mats Weber
  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 ` Matthew Heaney
@ 1997-04-22  0:00   ` Mats Weber
  1997-04-22  0:00     ` Matthew Heaney
                       ` (2 more replies)
  1997-04-22  0:00   ` Philip Brashear
  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-21  0:00 Equality operator overloading in ADA 83 Manuel Wenger
  1997-04-22  0:00 ` Kevin Cline
  1997-04-22  0:00 ` Matthew Heaney
@ 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

* Re: Equality operator overloading in ADA 83
  1997-04-22  0:00 ` Matthew Heaney
  1997-04-22  0:00   ` Mats Weber
@ 1997-04-22  0:00   ` Philip Brashear
  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     ` 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   ` Mats Weber
@ 1997-04-22  0:00     ` Matthew Heaney
  1997-04-23  0:00       ` Mats Weber
  1997-04-22  0:00     ` Robert A Duff
  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     ` 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-21  0:00 Equality operator overloading in ADA 83 Manuel Wenger
@ 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 ` Matthew Heaney
  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-21  0:00 Equality operator overloading in ADA 83 Manuel Wenger
  1997-04-22  0:00 ` Kevin Cline
@ 1997-04-22  0:00 ` Matthew Heaney
  1997-04-22  0:00   ` Mats Weber
  1997-04-22  0:00   ` Philip Brashear
  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-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-24  0:00             ` Mats Weber
  1997-04-23  0:00           ` Robert Dewar
  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       ` 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         ` Mats Weber
  1997-04-23  0:00           ` Robert A Duff
@ 1997-04-23  0:00           ` Robert Dewar
  1997-04-24  0:00             ` Robert A Duff
  1997-04-29  0:00             ` Mats Weber
  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-22  0:00       ` Matthew Heaney
@ 1997-04-23  0:00         ` Mats Weber
  1997-04-23  0:00           ` Robert A Duff
  1997-04-23  0:00           ` Robert Dewar
  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-22  0:00   ` Mats Weber
  1997-04-22  0:00     ` Matthew Heaney
  1997-04-22  0:00     ` Robert A Duff
@ 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-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-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             ` 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-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               ` Robert A Duff
@ 1997-04-24  0:00                 ` Robert Dewar
  1997-04-25  0:00                   ` Robert A Duff
  1997-04-25  0:00                 ` Mats Weber
                                   ` (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-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-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-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-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                 ` Kevin Cline
  1997-04-25  0:00                   ` Mats Weber
@ 1997-04-25  0:00                   ` Mats Weber
  1997-04-27  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)



> >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-24  0:00               ` Robert A Duff
  1997-04-24  0:00                 ` Robert Dewar
@ 1997-04-25  0:00                 ` Mats Weber
  1997-04-25  0:00                 ` Kevin Cline
  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-25  0:00                 ` Kevin Cline
@ 1997-04-25  0:00                   ` Mats Weber
  1997-04-25  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)



> >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               ` 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                 ` 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                   ` 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-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         ` 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-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-24  0:00               ` Robert A Duff
  1997-04-24  0:00                 ` Robert Dewar
  1997-04-25  0:00                 ` Mats Weber
@ 1997-04-25  0:00                 ` Kevin Cline
  1997-04-25  0:00                   ` Mats Weber
                                     ` (2 more replies)
  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             ` 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                 ` 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-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             ` 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-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
  1997-04-26  0:00                   ` Fergus Henderson
  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-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-24  0:00               ` Matthew Heaney
@ 1997-04-25  0:00                 ` Robert Dewar
  1997-04-25  0:00                   ` Matthew Heaney
  1997-04-25  0:00                 ` Robert Dewar
  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-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-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-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-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           ` 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-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-25  0:00                   ` Robert A Duff
@ 1997-04-26  0:00                     ` Nick Roberts
  1997-04-26  0:00                       ` Robert Dewar
                                         ` (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                   ` 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                     ` Nick Roberts
@ 1997-04-26  0:00                       ` Robert Dewar
  1997-04-26  0:00                         ` Matthew Heaney
  1997-04-26  0:00                       ` Robert A Duff
  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                     ` Nick Roberts
  1997-04-26  0:00                       ` Robert Dewar
@ 1997-04-26  0:00                       ` Robert A Duff
  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-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-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-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 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-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 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 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-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             ` 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-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                 ` 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-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                           ` 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-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-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-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-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-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-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-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-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                 ` 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-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               ` Robert A Duff
                                   ` (2 preceding siblings ...)
  1997-04-25  0:00                 ` Kevin Cline
@ 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-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-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-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-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-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-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-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-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-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                     ` 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-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-26  0:00                     ` Nick Roberts
  1997-04-26  0:00                       ` Robert Dewar
  1997-04-26  0:00                       ` Robert A Duff
@ 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-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-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-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-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-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-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-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

* 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-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-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
       [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-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-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-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
  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-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-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

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 ` Kevin Cline
1997-04-22  0:00   ` Mark A Biggar
1997-04-24  0:00   ` Keith Thompson
1997-04-22  0:00 ` Matthew Heaney
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 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-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 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 A Duff
1997-04-26  0:00                     ` Robert Dewar
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-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 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-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-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                 ` Mats Weber
1997-04-25  0:00                 ` Kevin Cline
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                   ` Mats Weber
1997-04-27  0:00                     ` Robert Dewar
1997-04-29  0:00                       ` Mats Weber
1997-04-25  0:00                   ` Robert A Duff
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-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-24  0:00         ` Robert Dewar
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   ` Philip Brashear
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