comp.lang.ada
 help / color / mirror / Atom feed
* renames usage
@ 2020-12-31 11:48 DrPi
  2020-12-31 12:10 ` John Perry
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: DrPi @ 2020-12-31 11:48 UTC (permalink / raw)



Hi,

One can read here 
https://github.com/AdaCore/svd2ada/blob/master/src/descriptors-field.adb#L83 
this line :

Tag   : String renames Elements.Get_Tag_Name (Child);

Is it equivalent to the following line ?

Tag   : String := Elements.Get_Tag_Name (Child);


Nicolas

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

* Re: renames usage
  2020-12-31 11:48 renames usage DrPi
@ 2020-12-31 12:10 ` John Perry
  2020-12-31 13:31   ` DrPi
  2020-12-31 12:33 ` Gautier write-only address
  2020-12-31 14:49 ` Jeffrey R. Carter
  2 siblings, 1 reply; 17+ messages in thread
From: John Perry @ 2020-12-31 12:10 UTC (permalink / raw)


No. Assignment copies the object, and changes to the copy don't affect the original, while renaming obtains a reference to the object. This program will illustrate it:

with Ada.Text_IO; use Ada.Text_IO;

procedure Test_Renames is

   S: String := "hello world";
   T: String := S;
   U: String renames S;

begin

   Put_Line(S);

   T(T'First) := 'y';
   Put_Line(S); -- still "hello world"

   U(U'First) := 'y';
   Put_Line(S); -- "yello world"

end Test_Renames;

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

* Re: renames usage
  2020-12-31 11:48 renames usage DrPi
  2020-12-31 12:10 ` John Perry
@ 2020-12-31 12:33 ` Gautier write-only address
  2020-12-31 14:49 ` Jeffrey R. Carter
  2 siblings, 0 replies; 17+ messages in thread
From: Gautier write-only address @ 2020-12-31 12:33 UTC (permalink / raw)


> Tag : String renames Elements.Get_Tag_Name (Child); 
> 
> Is it equivalent to the following line ? 
> 
> Tag : String := Elements.Get_Tag_Name (Child); 

Since the temporary object containing the result of the call "Elements.Get_Tag_Name (Child)" is not accessible anywhere else, the effect is the same.
But, perhaps in some implementations, the "renames" accesses that temporary object, which means the memory containing it must not be freed until Tag is out of scope. Perhaps it is even required. Any compiler specialist here?

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

* Re: renames usage
  2020-12-31 12:10 ` John Perry
@ 2020-12-31 13:31   ` DrPi
  0 siblings, 0 replies; 17+ messages in thread
From: DrPi @ 2020-12-31 13:31 UTC (permalink / raw)


Le 31/12/2020 à 13:10, John Perry a écrit :
> No. Assignment copies the object, and changes to the copy don't affect the original, while renaming obtains a reference to the object. This program will illustrate it:
> 
> with Ada.Text_IO; use Ada.Text_IO;
> 
> procedure Test_Renames is
> 
>     S: String := "hello world";
>     T: String := S;
>     U: String renames S;
> 
> begin
> 
>     Put_Line(S);
> 
>     T(T'First) := 'y';
>     Put_Line(S); -- still "hello world"
> 
>     U(U'First) := 'y';
>     Put_Line(S); -- "yello world"
> 
> end Test_Renames;
> 

Understood. Thanks.

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

* Re: renames usage
  2020-12-31 11:48 renames usage DrPi
  2020-12-31 12:10 ` John Perry
  2020-12-31 12:33 ` Gautier write-only address
@ 2020-12-31 14:49 ` Jeffrey R. Carter
  2020-12-31 15:55   ` DrPi
  2 siblings, 1 reply; 17+ messages in thread
From: Jeffrey R. Carter @ 2020-12-31 14:49 UTC (permalink / raw)


On 12/31/20 12:48 PM, DrPi wrote:
> 
> Tag   : String renames Elements.Get_Tag_Name (Child);
> 
> Is it equivalent to the following line ?
> 
> Tag   : String := Elements.Get_Tag_Name (Child);

No. A function result is a constant, so the 1st version gives you a constant. 
The second gives you a variable with the same value.

-- 
Jeff Carter
"There has also been a widespread acceptance ...
that program design is an important phase, too
often neglected in the past."
Elements of Programming Style
183

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

* Re: renames usage
  2020-12-31 14:49 ` Jeffrey R. Carter
@ 2020-12-31 15:55   ` DrPi
  2020-12-31 18:48     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 17+ messages in thread
From: DrPi @ 2020-12-31 15:55 UTC (permalink / raw)


Le 31/12/2020 à 15:49, Jeffrey R. Carter a écrit :
> On 12/31/20 12:48 PM, DrPi wrote:
>>
>> Tag   : String renames Elements.Get_Tag_Name (Child);
>>
>> Is it equivalent to the following line ?
>>
>> Tag   : String := Elements.Get_Tag_Name (Child);
> 
> No. A function result is a constant, so the 1st version gives you a 
> constant. The second gives you a variable with the same value.
> 
Good to know.
What disturbed me was the function call associated with "renames".

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

* Re: renames usage
  2020-12-31 15:55   ` DrPi
@ 2020-12-31 18:48     ` Dmitry A. Kazakov
  2021-01-01 12:39       ` DrPi
  0 siblings, 1 reply; 17+ messages in thread
From: Dmitry A. Kazakov @ 2020-12-31 18:48 UTC (permalink / raw)


On 2020-12-31 16:55, DrPi wrote:
> Le 31/12/2020 à 15:49, Jeffrey R. Carter a écrit :
>> On 12/31/20 12:48 PM, DrPi wrote:
>>>
>>> Tag   : String renames Elements.Get_Tag_Name (Child);
>>>
>>> Is it equivalent to the following line ?
>>>
>>> Tag   : String := Elements.Get_Tag_Name (Child);
>>
>> No. A function result is a constant, so the 1st version gives you a 
>> constant. The second gives you a variable with the same value.
>>
> Good to know.
> What disturbed me was the function call associated with "renames".

Renaming a call to a function does not rename it in some 
functional-programming manner. It renames only the result of.

So if you do

    X : Float renames Random (Seed);
    Y : array (1..10) of Float := (others => X);

That would not give you ten pseudo-random numbers. But this will:

    Z : array (1..10) of Float := (others => Random (Seed));

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: renames usage
  2020-12-31 18:48     ` Dmitry A. Kazakov
@ 2021-01-01 12:39       ` DrPi
  2021-01-01 13:20         ` Dmitry A. Kazakov
                           ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: DrPi @ 2021-01-01 12:39 UTC (permalink / raw)


Le 31/12/2020 à 19:48, Dmitry A. Kazakov a écrit :
> On 2020-12-31 16:55, DrPi wrote:
>> Le 31/12/2020 à 15:49, Jeffrey R. Carter a écrit :
>>> On 12/31/20 12:48 PM, DrPi wrote:
>>>>
>>>> Tag   : String renames Elements.Get_Tag_Name (Child);
>>>>
>>>> Is it equivalent to the following line ?
>>>>
>>>> Tag   : String := Elements.Get_Tag_Name (Child);
>>>
>>> No. A function result is a constant, so the 1st version gives you a 
>>> constant. The second gives you a variable with the same value.
>>>
>> Good to know.
>> What disturbed me was the function call associated with "renames".
> 
> Renaming a call to a function does not rename it in some 
> functional-programming manner. It renames only the result of.
> 
That's what I've understood with Jeffrey's answer.

> So if you do
> 
>     X : Float renames Random (Seed);
>     Y : array (1..10) of Float := (others => X);
> 
> That would not give you ten pseudo-random numbers. But this will:
> 
>     Z : array (1..10) of Float := (others => Random (Seed));
> 
Thanks for your detailed answer.


Reading all the answers, I understand that :
     X : Float renames Random (Seed);
is equivalent to :
     X : constant Float := Random (Seed);

Right ?

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

* Re: renames usage
  2021-01-01 12:39       ` DrPi
@ 2021-01-01 13:20         ` Dmitry A. Kazakov
  2021-01-02 11:53           ` DrPi
  2021-01-01 14:46         ` Jeffrey R. Carter
  2021-01-02 16:00         ` G.B.
  2 siblings, 1 reply; 17+ messages in thread
From: Dmitry A. Kazakov @ 2021-01-01 13:20 UTC (permalink / raw)


On 2021-01-01 13:39, DrPi wrote:

> Reading all the answers, I understand that :
>      X : Float renames Random (Seed);
> is equivalent to :
>      X : constant Float := Random (Seed);
> 
> Right ?

You must keep in mind that renaming ignores subtype contraints. So:

    X : Integer := -1;
    Y : Positive renames X; -- Let's fool ourselves
begin
    Put_Line ("A positive number " & Integer'Image (Y));

Will happily print "A positive number -1."

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: renames usage
  2021-01-01 12:39       ` DrPi
  2021-01-01 13:20         ` Dmitry A. Kazakov
@ 2021-01-01 14:46         ` Jeffrey R. Carter
  2021-01-02 11:55           ` DrPi
  2021-01-03  3:19           ` Randy Brukardt
  2021-01-02 16:00         ` G.B.
  2 siblings, 2 replies; 17+ messages in thread
From: Jeffrey R. Carter @ 2021-01-01 14:46 UTC (permalink / raw)


On 1/1/21 1:39 PM, DrPi wrote:
> 
> Reading all the answers, I understand that :
>      X : Float renames Random (Seed);
> is equivalent to :
>      X : constant Float := Random (Seed);

Technically, the renames gives a name to the anonymous temporary object returned 
by the function. The constant declaration makes a constant copy of it. So 
they're equivalent, but not identical.

However, the compiler is free to optimize the copy away, and I'd be surprised if 
there are any compilers that don't (except GNAT with -O0).

-- 
Jeff Carter
"My legs are gray, my ears are gnarled, my eyes are old and bent."
Monty Python's Life of Brian
81

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

* Re: renames usage
  2021-01-01 13:20         ` Dmitry A. Kazakov
@ 2021-01-02 11:53           ` DrPi
  0 siblings, 0 replies; 17+ messages in thread
From: DrPi @ 2021-01-02 11:53 UTC (permalink / raw)


Le 01/01/2021 à 14:20, Dmitry A. Kazakov a écrit :
> On 2021-01-01 13:39, DrPi wrote:
> 
>> Reading all the answers, I understand that :
>>      X : Float renames Random (Seed);
>> is equivalent to :
>>      X : constant Float := Random (Seed);
>>
>> Right ?
> 
> You must keep in mind that renaming ignores subtype contraints. So:
> 
>     X : Integer := -1;
>     Y : Positive renames X; -- Let's fool ourselves
> begin
>     Put_Line ("A positive number " & Integer'Image (Y));
> 
> Will happily print "A positive number -1."
> 
Interresting.
Thanks.

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

* Re: renames usage
  2021-01-01 14:46         ` Jeffrey R. Carter
@ 2021-01-02 11:55           ` DrPi
  2021-01-03  3:19           ` Randy Brukardt
  1 sibling, 0 replies; 17+ messages in thread
From: DrPi @ 2021-01-02 11:55 UTC (permalink / raw)


Le 01/01/2021 à 15:46, Jeffrey R. Carter a écrit :
> On 1/1/21 1:39 PM, DrPi wrote:
>>
>> Reading all the answers, I understand that :
>>      X : Float renames Random (Seed);
>> is equivalent to :
>>      X : constant Float := Random (Seed);
> 
> Technically, the renames gives a name to the anonymous temporary object 
> returned by the function. The constant declaration makes a constant copy 
> of it. So they're equivalent, but not identical.
> 
> However, the compiler is free to optimize the copy away, and I'd be 
> surprised if there are any compilers that don't (except GNAT with -O0).
> 
Effectively, the copy can be of importance in some situations.
Thanks.

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

* Re: renames usage
  2021-01-01 12:39       ` DrPi
  2021-01-01 13:20         ` Dmitry A. Kazakov
  2021-01-01 14:46         ` Jeffrey R. Carter
@ 2021-01-02 16:00         ` G.B.
  2021-01-02 17:22           ` Simon Wright
  2 siblings, 1 reply; 17+ messages in thread
From: G.B. @ 2021-01-02 16:00 UTC (permalink / raw)


On 01.01.21 13:39, DrPi wrote:

> Reading all the answers, I understand that :
>      X : Float renames Random (Seed);
> is equivalent to :
>      X : constant Float := Random (Seed);
> 
> Right ?

Also remember that limited types do not permit copying,
whether constant or not. Renaming avoids having to move
an object at all:

procedure Hammering is

    type Hammer is (Claw, Sledge);

    task type Nail is  -- A limited type
       entry Hit (Weight : Hammer);
    end Nail;

    task body Nail is separate;

    procedure Game is
       type Nail_Reference is access Nail;
       Challenge : array (1 .. 10) of Nail_Reference
         := (others => new Nail);

       function Random_Pick return Nail_Reference is
       begin
          return Challenge (2);
       end Random_Pick;

       Choice : Nail renames Random_Pick.all;
    begin
       Choice.Hit (Weight => Claw);
    end Game;

begin
    Game;
end Hammering;

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

* Re: renames usage
  2021-01-02 16:00         ` G.B.
@ 2021-01-02 17:22           ` Simon Wright
  0 siblings, 0 replies; 17+ messages in thread
From: Simon Wright @ 2021-01-02 17:22 UTC (permalink / raw)


"G.B." <bauhaus@notmyhomepage.invalid> writes:

> On 01.01.21 13:39, DrPi wrote:
>
>> Reading all the answers, I understand that :
>>      X : Float renames Random (Seed);
>> is equivalent to :
>>      X : constant Float := Random (Seed);
>> Right ?
>
> Also remember that limited types do not permit copying,
> whether constant or not. Renaming avoids having to move
> an object at all:

Another reason for renaming, which includes the above, would be
remembering a view conversion. The example to hand involves
Timing_Events.

The spec

   --  Support flashing an LED (for example, to indicate that a
   --  packet has been received from the controller).

   type Flasher (The_LED : not null access Crazyflie_LED)
     is tagged limited private;

   procedure Set (The_Flasher : in out Flasher);
   --  Lights the associated LED for 5 ms.

In the private part

   type Flasher (The_LED : not null access Crazyflie_LED)
     is new Ada.Real_Time.Timing_Events.Timing_Event with null record;

In the body

   protected Flasher_Handler is
      pragma Interrupt_Priority;
      procedure Turn_Off_The_LED            -- the Timing_Event_Handler
        (Event : in out ARTTE.Timing_Event);
      --  We "know" that the Event is actually a Flasher.
   end Flasher_Handler;

.. and finally

   protected body Flasher_Handler is
      procedure Turn_Off_The_LED
        (Event : in out ARTTE.Timing_Event) is
         The_Flasher : Flasher                                  -- <<<<
           renames Flasher (ARTTE.Timing_Event'Class (Event));  -- <<<<
      begin
         Set (The_Flasher.The_LED.all, False);
      end Turn_Off_The_LED;
   end Flasher_Handler;

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

* Re: renames usage
  2021-01-01 14:46         ` Jeffrey R. Carter
  2021-01-02 11:55           ` DrPi
@ 2021-01-03  3:19           ` Randy Brukardt
  2021-01-03 10:05             ` Jeffrey R. Carter
  1 sibling, 1 reply; 17+ messages in thread
From: Randy Brukardt @ 2021-01-03  3:19 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:rsnckg$h6v$1@dont-email.me...
> On 1/1/21 1:39 PM, DrPi wrote:
>>
>> Reading all the answers, I understand that :
>>  X : Float renames Random (Seed);
>> is equivalent to :
>>  X : constant Float := Random (Seed);
>
> Technically, the renames gives a name to the anonymous temporary object 
> returned by the function. The constant declaration makes a constant copy 
> of it. So they're equivalent, but not identical.
>
> However, the compiler is free to optimize the copy away, and I'd be 
> surprised if there are any compilers that don't (except GNAT with -O0).

In this case (a scalar return), the "copy" is a register, and it would be 
hard (and pointless) to eliminate that. It's more interesting for a function 
that returns a composite object, and in that case your answer is correct. 
Note that you can tell if a copy is made if there is a controlled component 
in the object.

One thing we've learned in language design is that nothing is ever exactly 
equivalent to something else. There's always subtle differences. Typical 
programmers can ignore such stuff, but not language designers.

                            Randy.


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

* Re: renames usage
  2021-01-03  3:19           ` Randy Brukardt
@ 2021-01-03 10:05             ` Jeffrey R. Carter
  2021-01-06  2:49               ` Randy Brukardt
  0 siblings, 1 reply; 17+ messages in thread
From: Jeffrey R. Carter @ 2021-01-03 10:05 UTC (permalink / raw)


On 1/3/21 4:19 AM, Randy Brukardt wrote:
> 
> In this case (a scalar return), the "copy" is a register, and it would be
> hard (and pointless) to eliminate that.

Thanks for the clarification. I'm not sure I understand what you mean by "the 
'copy' is a register". Do you mean

1. The return value has to be copied into a register

or

2. The return value is in a register and has to be copied elsewhere

?

-- 
Jeff Carter
"I'm a kike, a yid, a heebie, a hook nose! I'm Kosher,
Mum! I'm a Red Sea pedestrian, and proud of it!"
Monty Python's Life of Brian
77

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

* Re: renames usage
  2021-01-03 10:05             ` Jeffrey R. Carter
@ 2021-01-06  2:49               ` Randy Brukardt
  0 siblings, 0 replies; 17+ messages in thread
From: Randy Brukardt @ 2021-01-06  2:49 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:rss4sk$oqt$1@dont-email.me...
> On 1/3/21 4:19 AM, Randy Brukardt wrote:
>>
>> In this case (a scalar return), the "copy" is a register, and it would be
>> hard (and pointless) to eliminate that.
>
> Thanks for the clarification. I'm not sure I understand what you mean by 
> "the 'copy' is a register". Do you mean
>
> 1. The return value has to be copied into a register
>
> or
>
> 2. The return value is in a register and has to be copied elsewhere
>
> ?

The latter: on every machine on which I'm familar, scalar function results 
are returned in a register. That serves as the "return object", and there's 
not really any way to eliminate that short of inlining the entire call. To 
"rename" the result, one has to copy the register somewhere (unless of 
course the renaming lives a short time with no subprogram calls), and that 
is effectively the same as the constant object declaration.

OTOH, a composite object is typically returned with a reference in a 
register to memory allocated somewhere else (it might be passed in, it might 
be on a "secondary stack", it might be allocated, etc.), and one can rename 
rather than copy that memory.

Of course, if the type requires "build-in-place", then a renames and an 
object are essentially the same again, as no temporary is allowed and the 
memory has to be passed into the function; either for the constant or for 
the renamed temporary.

Which mainly goes to show that nothing is simple... :-)

                                 Randy.


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

end of thread, other threads:[~2021-01-06  2:49 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-31 11:48 renames usage DrPi
2020-12-31 12:10 ` John Perry
2020-12-31 13:31   ` DrPi
2020-12-31 12:33 ` Gautier write-only address
2020-12-31 14:49 ` Jeffrey R. Carter
2020-12-31 15:55   ` DrPi
2020-12-31 18:48     ` Dmitry A. Kazakov
2021-01-01 12:39       ` DrPi
2021-01-01 13:20         ` Dmitry A. Kazakov
2021-01-02 11:53           ` DrPi
2021-01-01 14:46         ` Jeffrey R. Carter
2021-01-02 11:55           ` DrPi
2021-01-03  3:19           ` Randy Brukardt
2021-01-03 10:05             ` Jeffrey R. Carter
2021-01-06  2:49               ` Randy Brukardt
2021-01-02 16:00         ` G.B.
2021-01-02 17:22           ` Simon Wright

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