comp.lang.ada
 help / color / mirror / Atom feed
* Interesting effects in array renaming
@ 2003-06-22 14:52 Dmitry A. Kazakov
  2003-06-22 17:24 ` Jeffrey Carter
  0 siblings, 1 reply; 20+ messages in thread
From: Dmitry A. Kazakov @ 2003-06-22 14:52 UTC (permalink / raw)


---------- test.adb
with Ada.Text_IO;  use Ada.Text_IO;

procedure Test is
   type Some_Array is array (Integer range <>) of Integer;

   procedure Foo (X : Some_Array) is
      subtype Constrained is Some_Array (1..X'Length);
      XX : Constrained renames X;
   begin
      Put_Line
      (  "XX'Range:"
      &  Integer'Image (XX'First)
      &  ".."
      &  Integer'Image (XX'Last)
      &  ", Constrained'Range:"
      &  Integer'Image (Constrained'First)
      &  ".."
      &  Integer'Image (Constrained'Last)
      );
   end Foo;

   Object : Some_Array (-3..2) := (-3, -2, -1, 0, 1, 2);
begin
   Foo (Object);
end Test;
---------- test.adb

Surprisingly the above produces different ranges for XX and its declared 
subtype. Isn't something wrong here?

I would expect either

1. XX'Range = Constrained'Range and indices are shifted

or

2. Raising Constraint_Error while renaming. How else could the compiler 
remove range checks for

X : Array_Subtype ...

for I in Array_Subtype'Range loop
   X (I) ...

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-22 14:52 Interesting effects in array renaming Dmitry A. Kazakov
@ 2003-06-22 17:24 ` Jeffrey Carter
  2003-06-23  8:12   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 20+ messages in thread
From: Jeffrey Carter @ 2003-06-22 17:24 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> ---------- test.adb
> with Ada.Text_IO;  use Ada.Text_IO;
> 
> procedure Test is
>    type Some_Array is array (Integer range <>) of Integer;
> 
>    procedure Foo (X : Some_Array) is
>       subtype Constrained is Some_Array (1..X'Length);
>       XX : Constrained renames X;
>    begin
>       Put_Line
>       (  "XX'Range:"
>       &  Integer'Image (XX'First)
>       &  ".."
>       &  Integer'Image (XX'Last)
>       &  ", Constrained'Range:"
>       &  Integer'Image (Constrained'First)
>       &  ".."
>       &  Integer'Image (Constrained'Last)
>       );
>    end Foo;
> 
>    Object : Some_Array (-3..2) := (-3, -2, -1, 0, 1, 2);
> begin
>    Foo (Object);
> end Test;
> ---------- test.adb
> 
> Surprisingly the above produces different ranges for XX and its declared 
> subtype. Isn't something wrong here?

Note that you can also do

subtype Constrained is Some_Array (1..X'Length-1);

or

subtype Constrained is Some_Array (1..3);

with similar results. You can also do

XX : Some_Array renames X;

which perhaps demonstrates more clearly where the object's subtype comes 
from.

-- 
Jeff Carter
"English bed-wetting types."
Monty Python & the Holy Grail




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-22 17:24 ` Jeffrey Carter
@ 2003-06-23  8:12   ` Dmitry A. Kazakov
  2003-06-23 10:29     ` Georg Bauhaus
  2003-06-24  2:35     ` Robert I. Eachus
  0 siblings, 2 replies; 20+ messages in thread
From: Dmitry A. Kazakov @ 2003-06-23  8:12 UTC (permalink / raw)


Jeffrey Carter wrote:

> Dmitry A. Kazakov wrote:
>> ---------- test.adb
>> with Ada.Text_IO;  use Ada.Text_IO;
>> 
>> procedure Test is
>>    type Some_Array is array (Integer range <>) of Integer;
>> 
>>    procedure Foo (X : Some_Array) is
>>       subtype Constrained is Some_Array (1..X'Length);
>>       XX : Constrained renames X;
>>    begin
>>       Put_Line
>>       (  "XX'Range:"
>>       &  Integer'Image (XX'First)
>>       &  ".."
>>       &  Integer'Image (XX'Last)
>>       &  ", Constrained'Range:"
>>       &  Integer'Image (Constrained'First)
>>       &  ".."
>>       &  Integer'Image (Constrained'Last)
>>       );
>>    end Foo;
>> 
>>    Object : Some_Array (-3..2) := (-3, -2, -1, 0, 1, 2);
>> begin
>>    Foo (Object);
>> end Test;
>> ---------- test.adb
>> 
>> Surprisingly the above produces different ranges for XX and its declared
>> subtype. Isn't something wrong here?
> 
> Note that you can also do
> 
> subtype Constrained is Some_Array (1..X'Length-1);
> 
> or
> 
> subtype Constrained is Some_Array (1..3);
> 
> with similar results. You can also do
>
> XX : Some_Array renames X;
> 
> which perhaps demonstrates more clearly where the object's subtype comes
> from.

I see no link with subtypes. ARM clearly states: 8.5.1(6)

"... any constraint implied by the subtype_mark of the 
object_renaming_declaration is ingored)."

I.e. whatever subtype you, a programmer, might specify I, the compiler, will 
shamelessly ignore it!

How safe! Do you really think it is OK? Consider this:

X1 : Constrained := Constrained (X);
X2 : Constrained renames X;

What is OK here, that X1 and X2 have different constraints or that X2 is 
potentially invalid?

I see only two alternatives:

Either to add a dynamic semantics ensuring that the result of renaming is a 
valid object of the declared subtype. [X2 raises Constraint_Error if 
Constrained'Range /= X'Range]

Or [painful] to require X1 and X2 be same in all cases, and thus:

   XX : Some_Array renames X (X'First + 1 .. X'Last);

would have length different from X, so a new array dope has to be generated 
etc.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-23  8:12   ` Dmitry A. Kazakov
@ 2003-06-23 10:29     ` Georg Bauhaus
  2003-06-23 11:37       ` Dmitry A. Kazakov
  2003-06-24  2:35     ` Robert I. Eachus
  1 sibling, 1 reply; 20+ messages in thread
From: Georg Bauhaus @ 2003-06-23 10:29 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
: 
: "... any constraint implied by the subtype_mark of the 
: object_renaming_declaration is ingored)."
: 
: I.e. whatever subtype you, a programmer, might specify I, the compiler, will 
: shamelessly ignore it!
: 
: How safe! Do you really think it is OK? Consider this:
 [...]
: I see only two alternatives:
: 
: Either to add a dynamic semantics ensuring that the result of renaming is a 
: valid object of the declared subtype. [X2 raises Constraint_Error if 
: Constrained'Range /= X'Range]
 
I think the compiler could warn about possibly
"incompatible" constraints in a renaming declaration.

Have you written to the producers of your compiler?



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-23 10:29     ` Georg Bauhaus
@ 2003-06-23 11:37       ` Dmitry A. Kazakov
  2003-06-23 13:28         ` Georg Bauhaus
  0 siblings, 1 reply; 20+ messages in thread
From: Dmitry A. Kazakov @ 2003-06-23 11:37 UTC (permalink / raw)


Georg Bauhaus wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> : 
> : "... any constraint implied by the subtype_mark of the
> : object_renaming_declaration is ingored)."
> : 
> : I.e. whatever subtype you, a programmer, might specify I, the compiler,
> : will shamelessly ignore it!
> : 
> : How safe! Do you really think it is OK? Consider this:
>  [...]
> : I see only two alternatives:
> : 
> : Either to add a dynamic semantics ensuring that the result of renaming
> : is a valid object of the declared subtype. [X2 raises Constraint_Error
> : if Constrained'Range /= X'Range]
>  
> I think the compiler could warn about possibly
> "incompatible" constraints in a renaming declaration.
> 
> Have you written to the producers of your compiler?

It is same in both GNAT and ObjectAda, but it is absolutely legal according 
to ARM. The problem is ARM itself. Which opens such a hole. What sense have 
our complains about buffer overruns in C/C++, in presense of this? It is 
also a range check optimization problem, because the compiler cannot rely 
on subtype information. Very bad.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-23 11:37       ` Dmitry A. Kazakov
@ 2003-06-23 13:28         ` Georg Bauhaus
  2003-06-24  7:35           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 20+ messages in thread
From: Georg Bauhaus @ 2003-06-23 13:28 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
: It is same in both GNAT and ObjectAda, but it is absolutely legal according 
: to ARM. The problem is ARM itself. Which opens such a hole. What sense have 
: our complains about buffer overruns in C/C++, in presense of this? It is 
: also a range check optimization problem, because the compiler cannot rely 
: on subtype information. Very bad.

I don't think it is so bad, it is much more an issue of what
renaming means, maybe? Most prominently, you give another name
to an entity, you don't make a new entity. Why should the new
name denote an entity wich has its bounds changed, despite
being "just another name"?

-- georg



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-23  8:12   ` Dmitry A. Kazakov
  2003-06-23 10:29     ` Georg Bauhaus
@ 2003-06-24  2:35     ` Robert I. Eachus
  2003-06-24  7:35       ` Dmitry A. Kazakov
  1 sibling, 1 reply; 20+ messages in thread
From: Robert I. Eachus @ 2003-06-24  2:35 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> I see no link with subtypes. ARM clearly states: 8.5.1(6)
> 
> "... any constraint implied by the subtype_mark of the 
> object_renaming_declaration is ingored)."
> 
> I.e. whatever subtype you, a programmer, might specify I, the compiler, will 
> shamelessly ignore it!
> 
> How safe! Do you really think it is OK? Consider this:

Let me give you a view into the the thinking behind this.  Renaming is 
just another way to create aliasing in Ada.  We couldn't do away with 
the aliasing provided by, for example, subprogram parameters, and all 
aliasing has the potential to create havoc.  The consensus was that Ada 
allows programmers to avoid aliasing, but it doesn't require programmers 
do so.

Why?  Because the havoc that can occur is only in the mind of the 
programmer.  There are a lot of validation tests that use aliasing to 
accomplish a particular purpose.  But the results of all those tests (at 
least in a conforming complier) is predictable.

The same applies in this case.  I often use aliasing "tricks" to make 
writing string handling code easier.  If a subprogam has a parameter say 
S: in String, you don't know that the S'First is 1.  But if you write: 
subtype S_String is String(1..S'Length); My_S: S_String renames S; now 
you can assume that the lower bound is 1.  But notice a detail here.  A 
renaming takes a subtype_mark rather than a subtype_indication.  In 
general when only a subtype mark is allowed in Ada, it indicates that 
what matters is the TYPE indicated by the subtype_mark.

In practice, I tend to write My_S: constant String(1..S'Length) := S; if 
that is what I want, because it also eliminates the possibility that S 
is passed by reference, and some other task modifies it.  But in general 
the question is how much (code and time) can I afford to spend making my 
library routine bulletproof.  Ada allows me to make that sort of 
tradeoff.

Also, it would seem to be a nice idea to either require that the 
constraints implied by subtype_mark in a renaming declaration be 
checked, or that the subtype_mark be a first named subtype.  The first 
doesn't work, because we already know that aliasing is going on. 
Checking the value at one point in time provides no real additional 
safety.  As for requiring the name be a first named subtype, I think 
that was in there at one point.  But it turned out to have problems, 
often the only subtype_mark available to you is an alias!  For example, 
renamings inside generics.  So this turns out to be one of those cases 
where Ada doesn't mandate good sense on the part of the programmer, and 
spends a lot of words covering all the different ways you MAY shoot 
yourself in the foot.

But as long as the semantics are defined, as I said way back at the top, 
the intended effect is the one in the programmers mind.  If that is not 
the required semantic effect, the programmer will be surprised. RM 
8.5.1(6) is pretty clear on what the programmer should expect: "An 
object_renaming_declaration declares a new view of the renamed object..."

If you expect a value conversion, sorry about that, what you get is a 
view conversion.  If you don't understand the difference between a value 
conversion and a view conversion, go reread RM 4.6.




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-23 13:28         ` Georg Bauhaus
@ 2003-06-24  7:35           ` Dmitry A. Kazakov
  2003-06-24 14:38             ` Georg Bauhaus
  0 siblings, 1 reply; 20+ messages in thread
From: Dmitry A. Kazakov @ 2003-06-24  7:35 UTC (permalink / raw)


Georg Bauhaus wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> : It is same in both GNAT and ObjectAda, but it is absolutely legal
> : according to ARM. The problem is ARM itself. Which opens such a hole.
> : What sense have our complains about buffer overruns in C/C++, in
> : presense of this? It is also a range check optimization problem, because
> : the compiler cannot rely on subtype information. Very bad.
> 
> I don't think it is so bad, it is much more an issue of what
> renaming means, maybe?

No, it is an issue of which meaning has an explicit specifying of a subtype. 
I would not object if the syntax were:

X : renames Y;

But it isn't.

> Most prominently, you give another name
> to an entity, you don't make a new entity.

Really? To me a "view" is definitely an "entity". You probably mean that 
renaming should not create a new object. But it is no matter, imposing a 
constraint on an existing object does not change the object. It is merely a 
precondition.

> Why should the new
> name denote an entity wich has its bounds changed, despite
> being "just another name"?

The answer depends on whether bounds is a property of (1) a value or of (2) 
a type. For an unconstrained array type you have (1), for a constrained 
array [sub]type (2). So when you rename one to another you have a clash 
between (1) and (2). It has to be reconciled. In the example I gave

for I in Constrained'Range loop
   X2 (I) := 0;
end loop;

may raise Constraint_Error or else corrupt memory if range checks are 
suppressed. It is abolutely unacceptable. To put it in one sentence: either 
you change bounds or you check them.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-24  2:35     ` Robert I. Eachus
@ 2003-06-24  7:35       ` Dmitry A. Kazakov
  2003-06-24 10:08         ` Lutz Donnerhacke
  2003-06-24 11:53         ` Georg Bauhaus
  0 siblings, 2 replies; 20+ messages in thread
From: Dmitry A. Kazakov @ 2003-06-24  7:35 UTC (permalink / raw)


Robert I. Eachus wrote:

> Dmitry A. Kazakov wrote:
> 
>> I see no link with subtypes. ARM clearly states: 8.5.1(6)
>> 
>> "... any constraint implied by the subtype_mark of the
>> object_renaming_declaration is ingored)."
>> 
>> I.e. whatever subtype you, a programmer, might specify I, the compiler,
>> will shamelessly ignore it!
>> 
>> How safe! Do you really think it is OK? Consider this:
> 
> Let me give you a view into the the thinking behind this.  Renaming is
> just another way to create aliasing in Ada.  We couldn't do away with
> the aliasing provided by, for example, subprogram parameters, and all
> aliasing has the potential to create havoc.  The consensus was that Ada
> allows programmers to avoid aliasing, but it doesn't require programmers
> do so.
> 
> Why?  Because the havoc that can occur is only in the mind of the
> programmer.  There are a lot of validation tests that use aliasing to
> accomplish a particular purpose.  But the results of all those tests (at
> least in a conforming complier) is predictable.
> 
> The same applies in this case.  I often use aliasing "tricks" to make
> writing string handling code easier.  If a subprogam has a parameter say
> S: in String, you don't know that the S'First is 1.  But if you write:
> subtype S_String is String(1..S'Length); My_S: S_String renames S; now
> you can assume that the lower bound is 1.

(?) You mean that I cannot, because My_S'First = S'First.

> But notice a detail here.  A
> renaming takes a subtype_mark rather than a subtype_indication.  In
> general when only a subtype mark is allowed in Ada, it indicates that
> what matters is the TYPE indicated by the subtype_mark.

Oh yes, ARM consistently states inconsistent things! (:-))
 
> In practice, I tend to write My_S: constant String(1..S'Length) := S; if
> that is what I want, because it also eliminates the possibility that S
> is passed by reference,

I usually declare a nested subprogram which takes S_String and does the 
things.

> and some other task modifies it.

I would not rely on it.

> But in general
> the question is how much (code and time) can I afford to spend making my
> library routine bulletproof.  Ada allows me to make that sort of
> tradeoff.
> 
> Also, it would seem to be a nice idea to either require that the
> constraints implied by subtype_mark in a renaming declaration be
> checked, or that the subtype_mark be a first named subtype.  The first
> doesn't work, because we already know that aliasing is going on.
> Checking the value at one point in time provides no real additional
> safety.

It povides additional safety for the reader of a program. [Isn't a goal Ada 
design?] It would allow to omit range checks many cases like:

procedure Sum (L : in out Vector; R : Vector) is
   subtype Of_L is Vector (L'Range);
   RR : Of_L renames R; -- Checked here
begin
   for I in L'Range loop
      L (I) := L (I) + RR (I); -- No range check needed

Far clearer than the trick with a nested subprogram:

procedure Sum (L : in out Vector; R : Vector) is
   subtype Of_L is Vector (L'Range);
   procedure Do_Sum (LL : in out Of_L; RR : Of_L) is
   begin
      for I in Of_L'Range loop
         LL (I) := LL (I) + RR (I); -- No range check needed
      end loop;
   end Do_Sum;
begin
   Do_Sum (L, R);

Presently Ada has no easy way to help the compiler in optimizing programs 
like above. Perhaps it will be achieved with preconditions if they at last 
appear in Ada. But even then I would expect:

X : S renames Y;

be equivalent to

ensure Y in S;
X : S renames Y;

> As for requiring the name be a first named subtype, I think
> that was in there at one point.  But it turned out to have problems,
> often the only subtype_mark available to you is an alias!  For example,
> renamings inside generics.  So this turns out to be one of those cases
> where Ada doesn't mandate good sense on the part of the programmer, and
> spends a lot of words covering all the different ways you MAY shoot
> yourself in the foot.
> 
> But as long as the semantics are defined, as I said way back at the top,
> the intended effect is the one in the programmers mind.  If that is not
> the required semantic effect, the programmer will be surprised. RM
> 8.5.1(6) is pretty clear on what the programmer should expect: "An
> object_renaming_declaration declares a new view of the renamed object..."

That the new view is wellcome to be inconsistent does not follow from that. 
It is written pair lines below. BTW, for tagged types it is different and 
semantically consistent:

procedure Foo (X : Base'Class) is
   XX : Derived renames X;           -- Illegal
   XX : Derived renames Derived (X); -- Legal and *CHECKED*

> If you expect a value conversion, sorry about that, what you get is a
> view conversion.  If you don't understand the difference between a value
> conversion and a view conversion, go reread RM 4.6.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-24  7:35       ` Dmitry A. Kazakov
@ 2003-06-24 10:08         ` Lutz Donnerhacke
  2003-06-24 11:53         ` Georg Bauhaus
  1 sibling, 0 replies; 20+ messages in thread
From: Lutz Donnerhacke @ 2003-06-24 10:08 UTC (permalink / raw)


* Dmitry A. Kazakov wrote:
> It povides additional safety for the reader of a program. [Isn't a goal Ada 
> design?] It would allow to omit range checks many cases like:
> 
> procedure Sum (L : in out Vector; R : Vector) is
>    subtype Of_L is Vector (L'Range);
>    RR : Of_L renames R; -- Checked here
> begin
>    for I in L'Range loop
>       L (I) := L (I) + RR (I); -- No range check needed

Currently this is not the case:

$ cat > test.adb <<END
procedure Test is
   type Vector is array (Integer range <>) of Integer;

   procedure Sum (L : in out Vector; R : Vector) is
      subtype Of_L is Vector (L'Range);
      RR : Of_L renames R; -- Checked here
   begin
      for I in L'Range loop
	 L (I) := L (I) + RR (I); -- No range check needed
      end loop;
   end Sum;
   
   a : Vector := (4 .. 10 => 4);
   b : Vector := (1, 2, 3);
begin
   Sum(a, b);
end Test;
END
$ gnatmake test
gcc -c test.adb
gnatbind -x test.ali
gnatlink test.ali
gnatlink: warning: executable name "test" may conflict with shell command
$ ./test
raised CONSTRAINT_ERROR : test.adb:10
$ sed -n 10p test.adb
         L (I) := L (I) + RR (I); -- No range check needed
$ _



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-24  7:35       ` Dmitry A. Kazakov
  2003-06-24 10:08         ` Lutz Donnerhacke
@ 2003-06-24 11:53         ` Georg Bauhaus
  2003-06-24 12:48           ` Dmitry A. Kazakov
  1 sibling, 1 reply; 20+ messages in thread
From: Georg Bauhaus @ 2003-06-24 11:53 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
: That the new view is wellcome to be inconsistent does not follow from that. 
: It is written pair lines below. BTW, for tagged types it is different and 
: semantically consistent:
: 
: procedure Foo (X : Base'Class) is
:   XX : Derived renames X;           -- Illegal
:   XX : Derived renames Derived (X); -- Legal and *CHECKED*

I'm not sure, considering

   procedure Foo (X : in out Varying'Class) is
      subtype Nono is Changeant (false);
      X1 : Changeant renames X;           -- Illegal
      X2 : Nono renames Changeant(X); -- Legal and *CHECKED*
   begin
      X2.messy := 2 * X2.messy; 
	-- constraint_error when discriminant is true
   end Foo;
 
where
package Derivs is

   type Varying (special: Boolean)
   is
     tagged record
        comp: Natural;
     end record;


   type Changeant (very_special: Boolean)
   is
     new Varying(very_special) with
      record
         case very_special is
            when true =>
               another: Boolean;
            when false =>
               messy: Integer;
         end case;
      end record;


end Derivs;


-- Georg



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-24 11:53         ` Georg Bauhaus
@ 2003-06-24 12:48           ` Dmitry A. Kazakov
  2003-06-26  2:54             ` Randy Brukardt
  0 siblings, 1 reply; 20+ messages in thread
From: Dmitry A. Kazakov @ 2003-06-24 12:48 UTC (permalink / raw)


Georg Bauhaus wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> : That the new view is wellcome to be inconsistent does not follow from
> : that. It is written pair lines below. BTW, for tagged types it is
> : different and semantically consistent:
> : 
> : procedure Foo (X : Base'Class) is
> :   XX : Derived renames X;           -- Illegal
> :   XX : Derived renames Derived (X); -- Legal and *CHECKED*
> 
> I'm not sure, considering
> 
>    procedure Foo (X : in out Varying'Class) is
>       subtype Nono is Changeant (false);
>       X1 : Changeant renames X;           -- Illegal
>       X2 : Nono renames Changeant(X); -- Legal and *CHECKED*

You could make it even more scandalous:

   X2 : Nono renames Nono(X); -- !!!No discriminant checks!!!

>    begin
>       X2.messy := 2 * X2.messy;
> -- constraint_error when discriminant is true
>    end Foo;
>  
> where
> package Derivs is
> 
>    type Varying (special: Boolean)
>    is
>      tagged record
>         comp: Natural;
>      end record;
>
>    type Changeant (very_special: Boolean)
>    is
>      new Varying(very_special) with
>       record
>          case very_special is
>             when true =>
>                another: Boolean;
>             when false =>
>                messy: Integer;
>          end case;
>       end record; 
> end Derivs;

Clarification: I meant tags, not discriminants (of possibly tagged types). 
What happens in your example, is the following. Nono has two constraints:

1. The discriminant very_special => False
2. The tag => Changeant'Tag (viewed as a constraint for any of the classes: 
Varying'Class, Changeant'Class)

When you rename X, the constraint 2 is checked. The constraint 1 is silently 
ignored as ARM requires.

Here we are. Now, convince me that it is GOOD.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-24  7:35           ` Dmitry A. Kazakov
@ 2003-06-24 14:38             ` Georg Bauhaus
  2003-06-25 10:28               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 20+ messages in thread
From: Georg Bauhaus @ 2003-06-24 14:38 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
: Georg Bauhaus wrote:
: 
:> I don't think it is so bad, it is much more an issue of what
:> renaming means, maybe?
: 
: No, it is an issue of which meaning has an explicit specifying of a subtype. 

Hm. 

  procedure foo(a: Apple) is
     p: Orange renames a;

may be correct, but confusing. Because, in my view a least, the
programmer is violating the usual meaning of "renames".
I think the bias is towards the wrong side/word if "Orange"
outweighs "renames".


:> Most prominently, you give another name
:> to an entity, you don't make a new entity.
: 
: Really? To me a "view" is definitely an "entity". You probably mean that 
: renaming should not create a new object.

Yes.

: But it is no matter, imposing a 
: constraint on an existing object does not change the object. It is merely a 
: precondition.

Should renaming be for imposing constraints?
If I rename myself as Bouwhouws, that won't change me I think,
and it doesn't impose a constraint on me. That's renaming for me.
It won't even change the sound of my name ;-)

: for I in Constrained'Range loop
:   X2 (I) := 0;
: end loop;
: 
: may raise Constraint_Error or else corrupt memory if range checks are 
: suppressed. It is abolutely unacceptable. To put it in one sentence: either 
: you change bounds or you check them.

But if you declare a subtype with constraints to be used in a renaming
declaration, then you know the constraints. You also know the bounds of
objects involved, by way of attributes. So you could make your intention
more explicit by using these known quantities if you want to avoid
copying.


-- sb463ba



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-24 14:38             ` Georg Bauhaus
@ 2003-06-25 10:28               ` Dmitry A. Kazakov
  2003-06-25 14:23                 ` Georg Bauhaus
  0 siblings, 1 reply; 20+ messages in thread
From: Dmitry A. Kazakov @ 2003-06-25 10:28 UTC (permalink / raw)


Georg Bauhaus wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> : Georg Bauhaus wrote:
> : 
> :> I don't think it is so bad, it is much more an issue of what
> :> renaming means, maybe?
> : 
> : No, it is an issue of which meaning has an explicit specifying of a
> : subtype.
> 
> Hm.
> 
>   procedure foo(a: Apple) is
>      p: Orange renames a;
> 
> may be correct, but confusing. Because, in my view a least, the
> programmer is violating the usual meaning of "renames".

But the "usual" meaning of "renames" is:

   p : renames a;

What meaning has Orange in renaming? Just a buzz word? Then I would propose 
to change the syntax to

   p: Orange or else renames a;

It would perfecly reflect the present semantics! (:-))

What I want is:

   p: Orange and then renames a;

> : But it is no matter, imposing a
> : constraint on an existing object does not change the object. It is
> : merely a precondition.
> 
> Should renaming be for imposing constraints?
> If I rename myself as Bouwhouws, that won't change me I think,
> and it doesn't impose a constraint on me.

It imposes a constraint on people calling you. That is the point. Consider 
renaming Mr.Smith to Mrs.Smith. Authorities in most contries would object, 
even if Mr.Smith had undergone a surgery. [Though, I could have missed the 
recent advances in "poltical correctness" and could be wrong] (:-))

> That's renaming for me.
> It won't even change the sound of my name ;-)

I give you another example. When you rename a routine:

   procedure Baz (A : Apple);
   procedure Foo (B : Apple) renames Baz;

the compiler checks the specified parameter profile. According to your 
theory it should not. Indeed

   procedure Foo (B : Orange) renames Baz;

by no means changes Baz.

> : for I in Constrained'Range loop
> :   X2 (I) := 0;
> : end loop;
> : 
> : may raise Constraint_Error or else corrupt memory if range checks are
> : suppressed. It is abolutely unacceptable. To put it in one sentence:
> : either you change bounds or you check them.
> 
> But if you declare a subtype with constraints to be used in a renaming
> declaration, then you know the constraints. You also know the bounds of
> objects involved, by way of attributes. So you could make your intention
> more explicit by using these known quantities if you want to avoid
> copying.

Oh, that's is the very C++ ideology to me:

"Wished it? Take it, idiot!" (:-))

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-25 10:28               ` Dmitry A. Kazakov
@ 2003-06-25 14:23                 ` Georg Bauhaus
  2003-06-25 19:00                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 20+ messages in thread
From: Georg Bauhaus @ 2003-06-25 14:23 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
: 
: But the "usual" meaning of "renames" is:
: 
:   p : renames a;

Opening the question of why theree is a subtype mentioned
in a renaming declaration. (Which I cannot answer, but I
find it consistent with other declarations, which involves
a subtypes name most of the times. Would you like
p: constant := a; ?)
 
:> Should renaming be for imposing constraints?
:> If I rename myself as Bouwhouws, that won't change me I think,
:> and it doesn't impose a constraint on me.
: 
: It imposes a constraint on people calling you.

I'd rather say it offers them the freedom to call me by that other
name, which additional freedom is not a constraint.

: Consider 
: renaming Mr.Smith to Mrs.Smith.

I think this is an example of changing the type (in some humans typing
scheme), or, if not, of changing the view, but _not_ the name,
which is "Smith". "Smith, come here, carry that chair!"

: I give you another example. When you rename a routine:
: 
:   procedure Baz (A : Apple);
:   procedure Foo (B : Apple) renames Baz;
: 
: the compiler checks the specified parameter profile. According to your 
: theory it should not. Indeed
: 
:   procedure Foo (B : Orange) renames Baz;
: 
: by no means changes Baz.

Well, if constraints and parameter profiles should get the same
treatment for reasons of consistency wrt to the criterion "checked"
in renaming declarations,  then, have you checked the implications
of such a change? I can't do this but after reading Robert's comments,
I trust this has been considered, with the result known.

I still think that a compiler warning will be useful.


-- georg



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-25 14:23                 ` Georg Bauhaus
@ 2003-06-25 19:00                   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 20+ messages in thread
From: Dmitry A. Kazakov @ 2003-06-25 19:00 UTC (permalink / raw)


Georg Bauhaus wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> : 
> : But the "usual" meaning of "renames" is:
> : 
> :   p : renames a;
> 
> Opening the question of why theree is a subtype mentioned
> in a renaming declaration. (Which I cannot answer, but I
> find it consistent with other declarations, which involves
> a subtypes name most of the times. Would you like
> p: constant := a; ?)

Not as a replacement to renaming, but probably as an enhancement towards 
type inference. It should have other semantics than renaming. It should 
create a new object if "a" is not constant in the context. Consider:

procedure Foo (a : in out Apple) is
   p : constant := a;
begin
   Eat (a); -- What happens with p?

Compare it with looking at a first glance reasonable:

p : constant Apple renames a; -- p view allows no changes on a

But it is a bad idea, because the contract here can be easily violated 
through the aliased view. Aliasing is not much compatible with invariants. 
So we should not pretend them existing.

Thus renaming should not only check whether the renamed object has the 
declared subtype, but also that this cannot be changed within the scope of 
the created view. For example:

type Vary (I : Integer) record
   case I is ...;
subtype Fixed is Vary (0);

X : Vary := ...;
Y : Fixed renames X; -- Illegal, one could change X.I in Y's scope.

> :> Should renaming be for imposing constraints?
> :> If I rename myself as Bouwhouws, that won't change me I think,
> :> and it doesn't impose a constraint on me.
> : 
> : It imposes a constraint on people calling you.
> 
> I'd rather say it offers them the freedom to call me by that other
> name, which additional freedom is not a constraint.

The constraint is that when they say "Bouwhouws", they should mean you. If 
"Bouwhouws" has any additional meaning it should be applicable to you, or 
at least not insult you. Otherwise, other people may think silly things of 
you. This does not impose any constraint on you. It only requires that a 
name fits you. So it imposes a constraint on the view.

> : Consider
> : renaming Mr.Smith to Mrs.Smith.
> 
> I think this is an example of changing the type (in some humans typing
> scheme), or, if not, of changing the view, but _not_ the name,
> which is "Smith". "Smith, come here, carry that chair!"

My Webster says that a name is "a word or combination of words by which a 
person or thing is reqularly known". Anyway the point was that though 
applying Mrs. to Mr.Smith would not change Smith, it would definitely 
insult him. So is it worth to try?

> : I give you another example. When you rename a routine:
> : 
> :   procedure Baz (A : Apple);
> :   procedure Foo (B : Apple) renames Baz;
> : 
> : the compiler checks the specified parameter profile. According to your
> : theory it should not. Indeed
> : 
> :   procedure Foo (B : Orange) renames Baz;
> : 
> : by no means changes Baz.
> 
> Well, if constraints and parameter profiles should get the same
> treatment for reasons of consistency wrt to the criterion "checked"
> in renaming declarations, then, have you checked the implications
> of such a change?

Technically I see no problems with additional subtype check. I cannot 
imagine any useful code which would rely on subtype violation in case of 
renaming.

More interesting would be to allow "violating" the constraints in a 
consitent way. I.e. to allow:

   procedure Foo (B : Orange) renames Baz;

and change the semantics of

   p : Orange renames a;

by corresponding subtype conversions:

   procedure Foo (B : Orange) is -- generated by the compiler
   begin
      Baz (Apple (B));
   end Foo;

   function Get_p return Orange is -- generated by the compiler
   begin
      return Orange (a);
   end Get_p;
   procedure Set_p (p : Orange) is -- generated by the compiler
   begin
      a := Apple (p);
   end Set_p;

But that would be much too radical to many.

> I can't do this but after reading Robert's comments,
> I trust this has been considered, with the result known.
> 
> I still think that a compiler warning will be useful.

Better than nothing. Unfortunately it cannot be statically checked.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-24 12:48           ` Dmitry A. Kazakov
@ 2003-06-26  2:54             ` Randy Brukardt
  2003-06-26  6:27               ` Vinzent Hoefler
  0 siblings, 1 reply; 20+ messages in thread
From: Randy Brukardt @ 2003-06-26  2:54 UTC (permalink / raw)


Dmitry A. Kazakov wrote in message ...
>Here we are. Now, convince me that it is GOOD.


I doubt anyone could do that, for the simple reason that you're right.
But there are a number of things about Ada that are wrong (the inability
to use "in out" parameters on functions is the most obvious to me), but
they're not going to be changed because of compatibility and/or
political reasons. That's the nature of the beast -- you'll never get
everything you want (or even close to it) -- and in total that might be
a good thing.

In the case of the renames, that would substantially change the
semantics of existing programs, both for renames themselves and for
generic in out parameters (which are defined in terms of renames). It
would be too much of a change - a lot of existing code would fail.

I find cases where the political process prevents needed fixes (like the
'in out' parameters on functions issue) much more annoying. At least in
the cases of compatibility, you can convince yourself that there really
is no choice...

                 Randy.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-26  2:54             ` Randy Brukardt
@ 2003-06-26  6:27               ` Vinzent Hoefler
  2003-06-26 12:44                 ` Georg Bauhaus
  0 siblings, 1 reply; 20+ messages in thread
From: Vinzent Hoefler @ 2003-06-26  6:27 UTC (permalink / raw)


Randy Brukardt wrote:

>But there are a number of things about Ada that are wrong (the inability
>to use "in out" parameters on functions is the most obvious to me),

In fact the idea that a function shall have no (or at least very
limited) side effects is a quite good one. Well, you still can use
global variables or access-Parameters to circumvent this restriction,
so perhaps one can consider it as rather inconsequential, but wrong?
No, I don't think so.


Vinzent.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-26  6:27               ` Vinzent Hoefler
@ 2003-06-26 12:44                 ` Georg Bauhaus
  2003-06-26 13:01                   ` Vinzent Hoefler
  0 siblings, 1 reply; 20+ messages in thread
From: Georg Bauhaus @ 2003-06-26 12:44 UTC (permalink / raw)


Vinzent Hoefler <ada.rocks@jlfencey.com> wrote:
: Randy Brukardt wrote:
: 
:>But there are a number of things about Ada that are wrong (the inability
:>to use "in out" parameters on functions is the most obvious to me),
: 
: In fact the idea that a function shall have no (or at least very
                       pure
: limited) side effects is a quite good one.

Image the name of the beast wasn't function.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Interesting effects in array renaming
  2003-06-26 12:44                 ` Georg Bauhaus
@ 2003-06-26 13:01                   ` Vinzent Hoefler
  0 siblings, 0 replies; 20+ messages in thread
From: Vinzent Hoefler @ 2003-06-26 13:01 UTC (permalink / raw)


Georg Bauhaus wrote:

>Vinzent Hoefler <ada.rocks@jlfencey.com> wrote:
>: Randy Brukardt wrote:
>: 
>:>But there are a number of things about Ada that are wrong (the inability
>:>to use "in out" parameters on functions is the most obvious to me),
>: 
>: In fact the idea that a function shall have no (or at least very
>                       pure
>: limited) side effects is a quite good one.
>
>Image the name of the beast wasn't function.

Well, I was thinking of VHDL and there exists the concept of pure and
impure functions. "pure" says, regardless of what happens, this
function will *always* return the same value for the same parameter
set with which it is called, but the "impure" function might read some
signal, so its return value might be different from the previous even
when called with the same parameters.

So i.e. SPARK's functions that should be free of side effects, are
really the equivalent to VHDL's _im_pure function like this one:

|impure function Check_Signal (Signal : Std_Logic) return Std_Logic is
|begin
|   return Global_State xor Signal;
|end Check_Signal;

So, no. A pure function (in a more mathematical sense) was not what I
was talking about.
Impure functions look ok for me, but they still shouldn't be able to
change their parameters or (more generally) the state of the system.


Vinzent.

-- 
Parents strongly cautioned  --  this  posting  is  intended for mature
audiences  over  18.  It  may  contain some material that many parents
would not find suitable for children and may include intense violence,
sexual situations, coarse language and suggestive dialogue.



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2003-06-26 13:01 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-22 14:52 Interesting effects in array renaming Dmitry A. Kazakov
2003-06-22 17:24 ` Jeffrey Carter
2003-06-23  8:12   ` Dmitry A. Kazakov
2003-06-23 10:29     ` Georg Bauhaus
2003-06-23 11:37       ` Dmitry A. Kazakov
2003-06-23 13:28         ` Georg Bauhaus
2003-06-24  7:35           ` Dmitry A. Kazakov
2003-06-24 14:38             ` Georg Bauhaus
2003-06-25 10:28               ` Dmitry A. Kazakov
2003-06-25 14:23                 ` Georg Bauhaus
2003-06-25 19:00                   ` Dmitry A. Kazakov
2003-06-24  2:35     ` Robert I. Eachus
2003-06-24  7:35       ` Dmitry A. Kazakov
2003-06-24 10:08         ` Lutz Donnerhacke
2003-06-24 11:53         ` Georg Bauhaus
2003-06-24 12:48           ` Dmitry A. Kazakov
2003-06-26  2:54             ` Randy Brukardt
2003-06-26  6:27               ` Vinzent Hoefler
2003-06-26 12:44                 ` Georg Bauhaus
2003-06-26 13:01                   ` Vinzent Hoefler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox