comp.lang.ada
 help / color / mirror / Atom feed
* Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
@ 2013-04-22 18:27 Shark8
  2013-04-22 19:13 ` Dmitry A. Kazakov
                   ` (3 more replies)
  0 siblings, 4 replies; 33+ messages in thread
From: Shark8 @ 2013-04-22 18:27 UTC (permalink / raw)


I recently ran into unexpected behavior in the differences between a normal return and an extended return [in GNAT]: namely an extended return used to generate items in an array of tasks will *ALWAYS* execute in a sequential manner whereas the array generated with an expression-function or normal return is executed simultaneously.

Is there some subtle difference in the extended return that I'm unaware of? (Is this a bug?)

--------------------
-- Experiment.adb --
--------------------
Pragma Ada_2012;

With
Ada.Text_IO,
Ada.Numerics.Float_Random
;

Procedure Experiment is

    -----------------------------------------------------
    -- RNG; This sets up random numbers for durations. --
    -----------------------------------------------------
    Package RNG is
	Function Random Return Duration;
    Private
	Use Ada.Numerics.Float_Random;
	G : Generator;
	Function Random Return Duration is
	    ( Duration( Random(G) ) );
    End RNG;
    
    Package Body RNG is
    Begin
	Ada.Numerics.Float_Random.Reset( G );
    End RNG;
    
    --------------------------------------------------
    -- Resource; Protected object handling Text-IO. --
    --------------------------------------------------
   protected Resource is
      procedure Write( Input : In String );
      procedure New_Line;
   private
   end Resource;
    
   protected body Resource is
      procedure Write( Input : In String ) is
      begin
         Ada.Text_IO.Put_Line( Input );
      end Write;

      Procedure New_Line is begin Write(""); end New_Line;
   end Resource;
    
    ---------------------------------------------------------
    -- Testing; This is the task-type we are playing with. --
    ---------------------------------------------------------
   Task Type Testing( Text : Not Null Access Constant String ) is
    end Testing;


   Task Body Testing is
      D : Duration := RNG.Random; -- Get a random duration.
    Begin
	delay  D; -- Delay for that duration.
      -- Then print the Text for the task as well as the Delay.
      Resource.Write( Text.ALL & ASCII.HT & Duration'Image(D) );
   End Testing;

    
    -- Make; these functions make an access-to-tasks for arrays.
    -- Note: these should all be equivelant.
   Function Make_EF(Input : in String) Return Not Null Access Testing is
    ( New Testing( Text => New String'(Input) ) );

   Function Make_ER(Input : in String) Return Not Null Access Testing is
   begin
      Return Result : Not Null Access Testing:= New Testing(New String'(Input));
   End Make_ER;

   Function Make_NR(Input : in String) Return Not Null Access Testing is
   begin
      Return New Testing(New String'(Input));
   End Make_NR;

    
Begin

    Resource.Write("TEST_1:"& ASCII.HT &"Expression Function");
    TEST_1:
    declare
	Function Make(Input : in String) Return Not Null Access Testing
	       Renames Make_EF;

	P : Constant Array (Positive Range <>) of
	  Not Null Access Constant Testing:=
	    ( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
    begin
	null;
    end TEST_1;
    Resource.New_Line;
    Resource.Write("TEST_2:"& ASCII.HT &"Normal Return Function");
    TEST_2:
    declare
	Function Make(Input : in String) Return Not Null Access Testing
	       Renames Make_NR;

	P : Constant Array (Positive Range <>) of
	  Not Null Access Constant Testing:=
	    ( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
    begin
	null;
    end TEST_2;
    Resource.New_Line;
    Resource.Write("TEST_3:"& ASCII.HT &"Extended Return Function");
    TEST_3:
    declare
	Function Make(Input : in String) Return Not Null Access Testing
	       Renames Make_ER;

	P : Constant Array (Positive Range <>) of
	  Not Null Access Constant Testing:=
	    ( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
    begin
	null;
    end TEST_3;
    Resource.New_Line;
    
   Resource.Write( "Terminating." );
End Experiment;



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-22 18:27 Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns Shark8
@ 2013-04-22 19:13 ` Dmitry A. Kazakov
  2013-04-22 20:11   ` Shark8
  2013-04-23  6:32 ` egilhh
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 33+ messages in thread
From: Dmitry A. Kazakov @ 2013-04-22 19:13 UTC (permalink / raw)


On Mon, 22 Apr 2013 11:27:09 -0700 (PDT), Shark8 wrote:

> I recently ran into unexpected behavior in the differences between a
> normal return and an extended return [in GNAT]: namely an extended return
> used to generate items in an array of tasks will *ALWAYS* execute in a
> sequential manner whereas the array generated with an expression-function
> or normal return is executed simultaneously.
> 
> Is there some subtle difference in the extended return that I'm unaware of? (Is this a bug?)

No difference (tested under Windows).

Issues with the code:

1. Add 2 s delay in each test in order to see all tasks completed. Delay
also causes context switching. When you use null statement the main task
likely to manage to create all contestant before any of them gains the
processor (depending on OS settings and number of cores available). 

2. The code leaks memory. I am sure you know that.

3. Do not return anonymous access objects created by allocator new. It is
almost always a bug.

4. Keywords to be written all lower case, if you want others be able to
read your code.

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



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-22 19:13 ` Dmitry A. Kazakov
@ 2013-04-22 20:11   ` Shark8
  2013-04-23  6:15     ` Simon Wright
                       ` (3 more replies)
  0 siblings, 4 replies; 33+ messages in thread
From: Shark8 @ 2013-04-22 20:11 UTC (permalink / raw)


On Monday, April 22, 2013 1:13:47 PM UTC-6, Dmitry A. Kazakov wrote:
> On Mon, 22 Apr 2013 11:27:09 -0700 (PDT), Shark8 wrote:
> 
> > I recently ran into unexpected behavior in the differences between a
> > normal return and an extended return [in GNAT]: namely an extended return
> > used to generate items in an array of tasks will *ALWAYS* execute in a
> > sequential manner whereas the array generated with an expression-function
> > or normal return is executed simultaneously.
> > 
> > Is there some subtle difference in the extended return that I'm unaware of? (Is this a bug?)
> 
> 
> No difference (tested under Windows).

Here's some output:

C:\Programming\Projects\temp\Experiment.exe
TEST_1:	Expression Function
Dave	 0.133781955
Bob	 0.304577380
Joey	 0.536659479
Steve	 0.699105740

TEST_2:	Normal Return Function
Joey	 0.226854607
Dave	 0.444059044
Steve	 0.499072224
Bob	 0.636090755

TEST_3:	Extended Return Function
Bob	 0.566724062
Steve	 0.118256144
Dave	 0.442499906
Joey	 0.711671948

Terminating.
[2013-04-22 14:00:45] process terminated successfully (elapsed time: 03.35s)

Notice that the second column (delay-time) of the first two test-cases is *ALWAYS* sorted in ascending order, this is as expected; the difference is the last test-case which is *NOT* in ascending order.

> Issues with the code:
> 
> 1. Add 2 s delay in each test in order to see all tasks completed.

... that's not an issue; they're all completing.

> Delay
> also causes context switching. When you use null statement the main task
> likely to manage to create all contestant before any of them gains the
> processor (depending on OS settings and number of cores available). 

I have four cores; that shouldn't be a problem though -- I'm using the protected object to manage my text-output debugging.

> 2. The code leaks memory. I am sure you know that.

It's rather irrelevant insofar as I know; this is only to illustrate that task-accesses are behaving differently with normal returns than they are for extended returns.

> 3. Do not return anonymous access objects created by allocator new. It is
> almost always a bug.

Yeah, adding a named access-type probably would clean up the code a little.

> 4. Keywords to be written all lower case, if you want others be able to
> read your code.

... and here I thought we had these nifty tools for formatting source-code according to the user's preference. It is not my fault these aren't well-integrated into your IDE/text-editor. -- IOW, if casing mattered I'd expect it to be enforced by the language.



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-22 20:11   ` Shark8
@ 2013-04-23  6:15     ` Simon Wright
  2013-04-23  7:35     ` Stephen Leake
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 33+ messages in thread
From: Simon Wright @ 2013-04-23  6:15 UTC (permalink / raw)


Shark8 <onewingedshark@gmail.com> writes:

> On Monday, April 22, 2013 1:13:47 PM UTC-6, Dmitry A. Kazakov wrote:

>> 4. Keywords to be written all lower case, if you want others be able
>> to read your code.
>
> ... and here I thought we had these nifty tools for formatting
> source-code according to the user's preference. It is not my fault
> these aren't well-integrated into your IDE/text-editor. -- IOW, if
> casing mattered I'd expect it to be enforced by the language.

It doesn't matter to the compiler, but Ada is intended to be read by
humans, and I agree with Dmitry.

And this particular code isn't in an IDE.



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-22 18:27 Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns Shark8
  2013-04-22 19:13 ` Dmitry A. Kazakov
@ 2013-04-23  6:32 ` egilhh
  2013-04-23 15:24   ` Adam Beneschan
  2013-04-23 16:00 ` Adam Beneschan
  2013-04-23 16:33 ` Simon Wright
  3 siblings, 1 reply; 33+ messages in thread
From: egilhh @ 2013-04-23  6:32 UTC (permalink / raw)


On Monday, April 22, 2013 8:27:09 PM UTC+2, Shark8 wrote:
> 
> 
>       Return Result : Not Null Access Testing:= New Testing(New String'(Input));

When the anonymous access type goes out of scope, it will block, waiting for 
the newly created task to complete. You can easily see what's happening if you
modify your task like this:

begin
Resource.Write(Text.all & "enter");
delay D + 10.0;
Resource.Write(Text.all & ASCII.HT & Duration'Image(D));


Not everyone has the same hardware as you, and your code may produce 
different results on less cores or slower computers. Adding a delay 2.0 as
Dmitry said, will reduce the likelyhood of that happening.

-- 
~egilhh

for those who don't 



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-22 20:11   ` Shark8
  2013-04-23  6:15     ` Simon Wright
@ 2013-04-23  7:35     ` Stephen Leake
  2013-04-23  8:58     ` Dmitry A. Kazakov
  2013-05-02  2:20     ` Randy Brukardt
  3 siblings, 0 replies; 33+ messages in thread
From: Stephen Leake @ 2013-04-23  7:35 UTC (permalink / raw)


Shark8 <onewingedshark@gmail.com> writes:

> Here's some output:

From what compiler version, on what OS, on what CPU?

>> 4. Keywords to be written all lower case, if you want others be able to
>> read your code.
>
> ... and here I thought we had these nifty tools for formatting
> source-code according to the user's preference. 

Way off base. This is a volunteer group, and there _is_ a common style
of lowercase for reserved words.

Yes, a pretty printer could rewrite your code, but that's an extra step;
every impediment between me and understanding your code makes it a
little less likely I will bother.

You could just as easily take that step, and save everyone else the
effort. Consider that part of the cost of deciding to not follow the
common style.
 
Being polite to the people you are asking to help you is only common
sense.

> It is not my fault
> these aren't well-integrated into your IDE/text-editor. 

Emacs Ada mode does not support that particular rewrite; no one has
asked for it! I'd have to use gnatpp on the command line. Which I've
_never_ had to resort to before for code posted in this newsgroup.

On the other hand, since Emacs Ada mode is an open source all-volunteer
effort, it _is_ your fault for not contributing support for gnatpp to
it, since you seem to feel it is important!

>-- IOW, if
> casing mattered I'd expect it to be enforced by the language.

There is a big difference between language rules and style rules; it's
time to learn that. Ada is case-insensitive for well established
software engineering reasons, and styles exist for equally well
established reasons. They are both required for successful projects;
they work together.

-- 
-- Stephe



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-22 20:11   ` Shark8
  2013-04-23  6:15     ` Simon Wright
  2013-04-23  7:35     ` Stephen Leake
@ 2013-04-23  8:58     ` Dmitry A. Kazakov
  2013-05-02  2:20     ` Randy Brukardt
  3 siblings, 0 replies; 33+ messages in thread
From: Dmitry A. Kazakov @ 2013-04-23  8:58 UTC (permalink / raw)


On Mon, 22 Apr 2013 13:11:41 -0700 (PDT), Shark8 wrote:

> On Monday, April 22, 2013 1:13:47 PM UTC-6, Dmitry A. Kazakov wrote:

>> 3. Do not return anonymous access objects created by allocator new. It is
>> almost always a bug.
> 
> Yeah, adding a named access-type probably would clean up the code a little.

No, it is not cleaning the code it is about having a bug. Anonymous access
types is an evil (as well as expression-functions, of course).

Anyway, the relevant RM section is 7.6.1(11). You have finalization
intermixed with the tasks warm-up. The result is a race condition.

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



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-23  6:32 ` egilhh
@ 2013-04-23 15:24   ` Adam Beneschan
  2013-04-24  5:56     ` egilhh
  0 siblings, 1 reply; 33+ messages in thread
From: Adam Beneschan @ 2013-04-23 15:24 UTC (permalink / raw)


On Monday, April 22, 2013 11:32:51 PM UTC-7, egilhh wrote:
> On Monday, April 22, 2013 8:27:09 PM UTC+2, Shark8 wrote:

> 
> >       Return Result : Not Null Access Testing:= New Testing(New String'(Input));
> 
> 
> 
> When the anonymous access type goes out of scope, it will block, waiting for 
> the newly created task to complete. 

But why wouldn't that affect Make_EF/Make_ER and Make_NR equally?  

I'm planning on delving into this further to figure out just what the rules are with respect to anonymous access types, task termination, and scope.  You may be right, but I'm not yet convinced.  (I mean, it's possible that this could explain the results with GNAT, but that doesn't mean GNAT is following the language correctly.)

  
> Not everyone has the same hardware as you, and your code may produce 
> different results on less cores or slower computers. Adding a delay 2.0 as
> Dmitry said, will reduce the likelyhood of that happening.

I just don't get this.  It's common for people asking questions about the language to post reduced cases or minimal code, i.e. to post the smallest code they can think of that demonstrates the problem.  This is a good thing, because it lets the rest of us focus on the actual question, rather than on details that are irrelevant to the question.  And everybody here is picking on his example as if this were production code.  Not to mention picking on his capitalization.

Sheesh.

                              -- Adam



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-22 18:27 Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns Shark8
  2013-04-22 19:13 ` Dmitry A. Kazakov
  2013-04-23  6:32 ` egilhh
@ 2013-04-23 16:00 ` Adam Beneschan
  2013-04-23 16:52   ` Simon Wright
  2013-05-02  2:28   ` Randy Brukardt
  2013-04-23 16:33 ` Simon Wright
  3 siblings, 2 replies; 33+ messages in thread
From: Adam Beneschan @ 2013-04-23 16:00 UTC (permalink / raw)


On Monday, April 22, 2013 11:27:09 AM UTC-7, Shark8 wrote:
> I recently ran into unexpected behavior in the differences between a normal return and an extended return [in GNAT]: namely an extended return used to generate items in an array of tasks will *ALWAYS* execute in a sequential manner whereas the array generated with an expression-function or normal return is executed simultaneously.
> 
> Is there some subtle difference in the extended return that I'm unaware of? (Is this a bug?)

OK, I think I've figured it out--egilhh was on the right track.  The
key rules are 7.6.1(4), "For the finalization of a master, dependent
tasks are first awaited, as explained in 9.3", and 9.3(2):

"If the task is created by the evaluation of an allocator for a given
access type, it depends on each master that includes the elaboration
of the declaration of the ultimate ancestor of the given access type."

The language here may be a bit sloppy, since for an anonymous access
type, I'm not sure there's any such thing as "the declaration of
... [a] given access type".  However, if this is interpreted as "the
declaration that causes the access type to be defined", then for
Make_ER, the declaration referred to is the extended return object
declaration, because that's the type that the allocator returns:

  Return Result : Not Null Access Testing:= New Testing(New String'(Input));

However, for Make_EF and Make_NR, the declaration is the function
declaration.  In Make_ER, the master that elaborates the extended
return object declaration (and therefore the anonymous access type
declaration) is the body of Make_ER.  (For the other cases, the
master that elaborates the declaration is the Experiment procedure.)

The upshot of all this is that, by 7.6.1(4) and 9.3(2), in Make_ER,
the task created by the allocator *depends* *on* the body of Make_ER,
and therefore the body of Make_ER cannot complete until the task has
completed.  That should be enough to explain the results.

The moral: Whether or not you think anonymous access types are evil,
anonymous access types to *tasks* definitely can have some surprising
consequences (because of the task termination and dependency rules),
and should be avoided.

                         -- Adam




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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-22 18:27 Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns Shark8
                   ` (2 preceding siblings ...)
  2013-04-23 16:00 ` Adam Beneschan
@ 2013-04-23 16:33 ` Simon Wright
  3 siblings, 0 replies; 33+ messages in thread
From: Simon Wright @ 2013-04-23 16:33 UTC (permalink / raw)


Shark8 <onewingedshark@gmail.com> writes:

> I recently ran into unexpected behavior in the differences between a
> normal return and an extended return [in GNAT]: namely an extended
> return used to generate items in an array of tasks will *ALWAYS*
> execute in a sequential manner whereas the array generated with an
> expression-function or normal return is executed simultaneously.
>
> Is there some subtle difference in the extended return that I'm
> unaware of? (Is this a bug?)

I'm pretty sure you've found a bug.

I changed Testing to have an entry Start, and changed the body to report
when the task was activated:

   task type Testing( Text : not null access constant String ) is
      entry Start;
   end Testing;

   task body Testing is
      D : Duration := RNG.Random; -- Get a random duration.
   begin
      Resource.Write (Text.all & " starting.");
      accept Start;
      delay  D; -- Delay for that duration.
                -- Then print the Text for the task as well as the Delay.
      Resource.Write( Text.all & ASCII.HT & Duration'Image(D) );
   end Testing;

and changed the three test loops to start the tasks

    begin
       for T of P loop
          T.Start;
       end loop;
    end TEST_3;

The expression function and normal return function versions were fine;
the extended return function version prints

   TEST_3:	Extended Return Function
   Bob starting.

and hangs.




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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-23 16:00 ` Adam Beneschan
@ 2013-04-23 16:52   ` Simon Wright
  2013-04-23 17:57     ` Adam Beneschan
  2013-04-23 23:00     ` Shark8
  2013-05-02  2:28   ` Randy Brukardt
  1 sibling, 2 replies; 33+ messages in thread
From: Simon Wright @ 2013-04-23 16:52 UTC (permalink / raw)


Adam Beneschan <adam@irvine.com> writes:

> The upshot of all this is that, by 7.6.1(4) and 9.3(2), in Make_ER,
> the task created by the allocator *depends* *on* the body of Make_ER,
> and therefore the body of Make_ER cannot complete until the task has
> completed.  That should be enough to explain the results.

Yes, but there are other similar side effects: in the tests, OP wrote

    declare
	function Make(Input : in String) return not null access Testing
	       renames Make_EF;

	P : constant array (Positive range <>) of
	  not null access constant Testing:=
	    ( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
    begin
       null;
    end TEST_1;

and the code doesn't exit the declare block until all the tasks have
completed.

With the original code (modified as in my previous post) the output is

   TEST_1:	Expression Function
   Bob starting.
   Steve starting.
   Dave starting.
   Joey starting.
   Joey	 0.163312241
   Dave	 0.177723214
   Steve 0.354075342
   Bob	 0.573863626

   TEST_2:	Normal Return Function
   Bob starting.
   Steve starting.
   Dave starting.
   Joey starting.
   Dave	 0.302558333
   Steve 0.427543312
   Bob	 0.457369596
   Joey	 0.469346672

   TEST_3:	Extended Return Function
   Bob starting.

whereas changing 'not null access Testing' to a named access type
'Testing_P'

gives

   TEST_1:	Expression Function
   Bob starting.
   Steve starting.
   Dave starting.
   Joey starting.

   TEST_2:	Normal Return Function
   Bob starting.
   Steve starting.
   Dave starting.
   Joey starting.

   TEST_3:	Extended Return Function
   Bob starting.
   Steve starting.
   Dave starting.
   Joey starting.

   Terminating.
   Joey	 0.030557213
   Bob	 0.052638587
   Steve 0.076554827
   Bob	 0.104827218
   Bob	 0.122844748
   Dave	 0.315774351
   Dave	 0.446240813
   Joey	 0.512601733
   Joey	 0.560874224
   Steve 0.698063731
   Dave	 0.702636242
   Steve 0.852463245

By the way, what's the significance of 'constant' in 'not null access
constant Testing'?

> The moral: Whether or not you think anonymous access types are evil,
> anonymous access types to *tasks* definitely can have some surprising
> consequences (because of the task termination and dependency rules),
> and should be avoided.

This.



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-23 16:52   ` Simon Wright
@ 2013-04-23 17:57     ` Adam Beneschan
  2013-04-25  8:48       ` egilhh
  2013-05-02  2:38       ` Randy Brukardt
  2013-04-23 23:00     ` Shark8
  1 sibling, 2 replies; 33+ messages in thread
From: Adam Beneschan @ 2013-04-23 17:57 UTC (permalink / raw)


On Tuesday, April 23, 2013 9:52:04 AM UTC-7, Simon Wright wrote:
> 
> > The upshot of all this is that, by 7.6.1(4) and 9.3(2), in Make_ER,
> > the task created by the allocator *depends* *on* the body of Make_ER,
> > and therefore the body of Make_ER cannot complete until the task has
> > completed.  That should be enough to explain the results.
> 
> Yes, but there are other similar side effects: in the tests, OP wrote
> 
>     declare
> 	function Make(Input : in String) return not null access Testing
> 	       renames Make_EF;
> 
> 	P : constant array (Positive range <>) of
> 	  not null access constant Testing:=
> 	    ( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
>     begin
>        null;
>     end TEST_1;
> 
> and the code doesn't exit the declare block until all the tasks have
> completed.

I don't see a language reason for that.  The tasks are all created with allocators, and the type of the allocator alone should determine what master the tasks depend on--not a block declaring an array that contains the access objects.  If it's true that the block doesn't exit until all the tasks created by allocators have completed, then it's probably a GNAT bug.  I'd need to study it more carefully to make sure, though.  There may be some relevant language rules I'm missing, or something else I'm missing.

                              -- Adam



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-23 16:52   ` Simon Wright
  2013-04-23 17:57     ` Adam Beneschan
@ 2013-04-23 23:00     ` Shark8
  2013-04-23 23:16       ` Adam Beneschan
  1 sibling, 1 reply; 33+ messages in thread
From: Shark8 @ 2013-04-23 23:00 UTC (permalink / raw)


On Tuesday, April 23, 2013 10:52:04 AM UTC-6, Simon Wright wrote:
> 
> By the way, what's the significance of 'constant' in 'not null access
> constant Testing'?

It means you can't swap the task-access out w/ a new allocator -- Though you might not be able to do that anyway. -- I was going for the most constrained types/conditions possible while I was experimenting.

> 
> > The moral: Whether or not you think anonymous access types are evil,
> > anonymous access types to *tasks* definitely can have some surprising
> > consequences (because of the task termination and dependency rules),
> > and should be avoided.
> 

Yes; this was surprising. Though this brings up an interesting point: how would you be able to have an array of tasks that have a discriminant?



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-23 23:00     ` Shark8
@ 2013-04-23 23:16       ` Adam Beneschan
  0 siblings, 0 replies; 33+ messages in thread
From: Adam Beneschan @ 2013-04-23 23:16 UTC (permalink / raw)


On Tuesday, April 23, 2013 4:00:20 PM UTC-7, Shark8 wrote:

> > > The moral: Whether or not you think anonymous access types are evil,
> > > anonymous access types to *tasks* definitely can have some surprising
> > > consequences (because of the task termination and dependency rules),
> > > and should be avoided.
> 
> Yes; this was surprising. Though this brings up an interesting point: how would you be able to have an array of tasks that have a discriminant?

What I said applies to *anonymous* access types, not named access types.  You can still get what you want by defining a named access type inside Experiment (or globally in another package); this won't have the same pitfall with task termination.

Ada does have a problem with arrays of tasks with discriminants; see http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0061-1.txt?rev=1.1 for a proposed solution, but I doubt that will be part of the language for some time.

                            -- Adam



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-23 15:24   ` Adam Beneschan
@ 2013-04-24  5:56     ` egilhh
  2013-04-24 14:40       ` Adam Beneschan
  0 siblings, 1 reply; 33+ messages in thread
From: egilhh @ 2013-04-24  5:56 UTC (permalink / raw)


On Tuesday, April 23, 2013 5:24:29 PM UTC+2, Adam Beneschan wrote:
> On Monday, April 22, 2013 11:32:51 PM UTC-7, egilhh wrote:
> 
> > Not everyone has the same hardware as you, and your code may produce 
> 
> > different results on less cores or slower computers. Adding a delay 2.0 as
> 
> > Dmitry said, will reduce the likelyhood of that happening.
> 
> 
> 
> I just don't get this.  It's common for people asking questions about the language to post reduced cases or minimal code, i.e. to post the smallest code they can think of that demonstrates the problem.  This is a good thing, because it lets the rest of us focus on the actual question, rather than on details that are irrelevant to the question.  And everybody here is picking on his example as if this were production code.  Not to mention picking on his capitalization.
> 

Well, I don't get this. I was trying to point out that without a 2 sec delay, 
there's a risk of running multiple tests in parallel. I don't know about you,
but to me that's a bad thing, even if it's not production code. On my computer,
for example, the output of tasks from the different tests got mixed up. I may
agree that I could have phrased it differently, but I can't see the reason for
anyone to read it in the worst possible way. 

Sheesh, was it?

-- 
~egilhh



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-24  5:56     ` egilhh
@ 2013-04-24 14:40       ` Adam Beneschan
  2013-04-25  5:30         ` egilhh
  0 siblings, 1 reply; 33+ messages in thread
From: Adam Beneschan @ 2013-04-24 14:40 UTC (permalink / raw)


On Tuesday, April 23, 2013 10:56:46 PM UTC-7, egilhh wrote:

> Well, I don't get this. I was trying to point out that without a 2 sec delay, 
> there's a risk of running multiple tests in parallel. I don't know about you,
> but to me that's a bad thing, even if it's not production code. 

When one writes code whose only purpose is to demonstrate a possible compiler problem, or ask a question about why the language is the way it is, one does not try to write good code.  So what's the point of pointing out the flaws in his code?

The fact that the output of tests got mixed up isn't related to the symptom the OP was talking about.  His symptom pertained only to the order in which one of the tests generated its own output.

On the other hand, it's interesting to me that the output of the tests is getting mixed up, because that's the behavior I'd expect if the compiler was determining task masters correctly.  Simon, if I understood correctly, seemed to get a result where the output of the tests was *not* mixed up and a block was waiting for its tasks to terminate before the program moved on to the next test.  That would indicate a compiler bug of some sort, if I understand the language rules properly.  Interesting.

                           -- Adam





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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-24 14:40       ` Adam Beneschan
@ 2013-04-25  5:30         ` egilhh
  2013-04-25  5:41           ` Shark8
  0 siblings, 1 reply; 33+ messages in thread
From: egilhh @ 2013-04-25  5:30 UTC (permalink / raw)


On Wednesday, April 24, 2013 4:40:28 PM UTC+2, Adam Beneschan wrote:
> 
> 
> The fact that the output of tests got mixed up isn't related to the symptom the OP was talking about. 

But it is, when others are trying to reproduce the problem. When the order of
output from three tests are intertwined, how do I know the order of output from
one of them?


-- 
~egilhh




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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-25  5:30         ` egilhh
@ 2013-04-25  5:41           ` Shark8
  0 siblings, 0 replies; 33+ messages in thread
From: Shark8 @ 2013-04-25  5:41 UTC (permalink / raw)


On Wednesday, April 24, 2013 11:30:49 PM UTC-6, egilhh wrote:
> On Wednesday, April 24, 2013 4:40:28 PM UTC+2, Adam Beneschan wrote:
> 
> > The fact that the output of tests got mixed up isn't related to the symptom the OP was talking about. 
> 
> But it is, when others are trying to reproduce the problem. When the order of
> output from three tests are intertwined, how do I know the order of output from
> one of them?

The ordering became intermingled when I replaced the anonymous accesses with a named type; however, it did not occur in the code as presented on a Windows GNAT GPL ststem [quad-core].

That instance is something else that was surprising; intuitively, exiting the declare block should have only happened when the tasks were finished (and then all their allocations [which were local but no longer exist] should be cleaned up (just as returning on a function should clear the local variables on the stack).



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-23 17:57     ` Adam Beneschan
@ 2013-04-25  8:48       ` egilhh
  2013-04-25 15:19         ` Adam Beneschan
  2013-05-02  2:33         ` Randy Brukardt
  2013-05-02  2:38       ` Randy Brukardt
  1 sibling, 2 replies; 33+ messages in thread
From: egilhh @ 2013-04-25  8:48 UTC (permalink / raw)


On Tuesday, April 23, 2013 7:57:56 PM UTC+2, Adam Beneschan wrote:
> On Tuesday, April 23, 2013 9:52:04 AM UTC-7, Simon Wright wrote:
> 
>  
> I don't see a language reason for that.  The tasks are all created with allocators, and the type of the allocator alone should determine what master the tasks depend on--not a block declaring an array that contains the access objects.  If it's true that the block doesn't exit until all the tasks created by allocators have completed, then it's probably a GNAT bug.  I'd need to study it more carefully to make sure, though.  There may be some relevant language rules I'm missing, or something else I'm missing.
> 

I've been reading up on the accessibility rules (RM 3.10.2), and the rules
for functions returning anonymous access types have changed from 2005 to 2012.
In my understanding, 2012 now requires the block to wait:

RM 3.10.2(10.1/3): "The accessibility level of the result of a function call is
that of the master of the function call, which is determined by the point of
call as follows:"

RM 3.10.2(10.2/3): "If the result is used (in its entirety) to directly
initialize part of an object, the master is that of the object being
initialized. In the case where the initialized object is a coextension (see
below) that becomes a coextension of another object, the master is that of the
eventual object to which the coextension will be transferred."

RM 3.10.2(10.7/3): "In the case of a call to a function whose result type
is an anonymous access type, the accessibility level of the type of the result
of the function call is also determined by the point of call as described
above"),

whereas 2005 permitted the other behavior. (A language lawyer is needed to
confirm this)


-- 
~egilhh



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-25  8:48       ` egilhh
@ 2013-04-25 15:19         ` Adam Beneschan
  2013-05-02  2:33         ` Randy Brukardt
  1 sibling, 0 replies; 33+ messages in thread
From: Adam Beneschan @ 2013-04-25 15:19 UTC (permalink / raw)


On Thursday, April 25, 2013 1:48:47 AM UTC-7, egilhh wrote:

> > I don't see a language reason for that.  The tasks are all created with allocators, and the type of the allocator alone should determine what master the tasks depend on--not a block declaring an array that contains the access objects.  If it's true that the block doesn't exit until all the tasks created by allocators have completed, then it's probably a GNAT bug.  I'd need to study it more carefully to make sure, though.  There may be some relevant language rules I'm missing, or something else I'm missing.

> I've been reading up on the accessibility rules (RM 3.10.2), and the rules
> for functions returning anonymous access types have changed from 2005 to 2012.
> In my understanding, 2012 now requires the block to wait:
> 
> RM 3.10.2(10.1/3): "The accessibility level of the result of a function call is
> that of the master of the function call, which is determined by the point of
> call as follows:"
> 
> RM 3.10.2(10.2/3): "If the result is used (in its entirety) to directly
> initialize part of an object, the master is that of the object being
> initialized. In the case where the initialized object is a coextension (see
> below) that becomes a coextension of another object, the master is that of the
> eventual object to which the coextension will be transferred."
> 
> RM 3.10.2(10.7/3): "In the case of a call to a function whose result type
> is an anonymous access type, the accessibility level of the type of the result
> of the function call is also determined by the point of call as described
> above"),
> 
> whereas 2005 permitted the other behavior. (A language lawyer is needed to
> confirm this)

Offhand, I don't think these new rules are relevant to this particular question.  They define the "master of a function call".  However, the master on which a task created by an allocator depends is the "master that includes the elaboration of the declaration of the ultimate ancestor of the given access type" (9.3(2)), which I think is different.  Basically, I think that if the new rules in 3.10.2 were supposed to impact how a master is computed for an allocator that returns anonymous-access-to-task, something would have to be changed in 9.3(2) as well.  Also, I think that the new changes were supposed to change how accessibility levels are determined (for the purposes of doing accessibility checks and preventing dangling references), not to change what tasks depend on.  But I could be wrong, and it's certainly possible that this was a combination of features that escaped the notice of the language designers when this change was made.

Thanks for finding the new rules; I wasn't really aware of them (I was aware that there were some changes but I didn't know much about what they were).  I really am not sure my analysis is correct.  Probably, a language lawyer who was involved in AI05-234 needs to weigh in.  I'll probably try to read that AI also to see if accesses-to-tasks and/or task dependence were discussed at all, and what was said about them.  The whole thing is pretty confusing.

                            -- Adam



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-22 20:11   ` Shark8
                       ` (2 preceding siblings ...)
  2013-04-23  8:58     ` Dmitry A. Kazakov
@ 2013-05-02  2:20     ` Randy Brukardt
  2013-05-02  4:41       ` Shark8
  3 siblings, 1 reply; 33+ messages in thread
From: Randy Brukardt @ 2013-05-02  2:20 UTC (permalink / raw)


"Shark8" <onewingedshark@gmail.com> wrote in message 
news:e0c67da2-159a-4a37-b199-1d80312f6aca@googlegroups.com...
...
>> Delay
>> also causes context switching. When you use null statement the main task
>> likely to manage to create all contestant before any of them gains the
>> processor (depending on OS settings and number of cores available).

>I have four cores; that shouldn't be a problem though -- I'm using the 
>protected
>object to manage my text-output debugging.

But doing that is a Bounded_Error (see 9.5.1(8-18), and specifically 
paragraph 18).

It of course might work as you intend (that's one of the possible results), 
but its something you should avoid in code unless you never, ever expect to 
run it on a different Ada compiler.

To do this correctly, you have to use a lock object, typically wrapped in a 
controlled object so that initialization does the locking and finalization 
does the unlocking (that way you don't have to worry about abort or 
exceptions screwing up your locking). I'll leave the code needed as an 
exercise for the OP. :-)

                          Randy.


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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-23 16:00 ` Adam Beneschan
  2013-04-23 16:52   ` Simon Wright
@ 2013-05-02  2:28   ` Randy Brukardt
  2013-05-02 16:37     ` Adam Beneschan
  1 sibling, 1 reply; 33+ messages in thread
From: Randy Brukardt @ 2013-05-02  2:28 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:f91ac67c-02c9-43fd-982c-a58567aa9a1b@googlegroups.com...
...
>"If the task is created by the evaluation of an allocator for a given
>access type, it depends on each master that includes the elaboration
>of the declaration of the ultimate ancestor of the given access type."
>
>The language here may be a bit sloppy, since for an anonymous access
>type, I'm not sure there's any such thing as "the declaration of
>... [a] given access type".

Wow, I think we've missed this Adam for a while! I'm pretty sure there is 
wording somewhere that says that where an anonymous access type is declared, 
but I'm not going to look it up right now. We spent way too much time 
rewriting this wording for Ada 2012, so I'm pretty sure it is consistent 
(now - the Ada 2005 wording was garbage).

...
>The moral: Whether or not you think anonymous access types are evil,
>anonymous access types to *tasks* definitely can have some surprising
>consequences (because of the task termination and dependency rules),
>and should be avoided.

You should extend this to anything that gets finalized, because you get the 
same sorts of issues with them. And since *everything* ought to be 
controlled (IMHO), ergo you have to avoid all anonymous access types. QED. 
:-)

                               Randy.


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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-25  8:48       ` egilhh
  2013-04-25 15:19         ` Adam Beneschan
@ 2013-05-02  2:33         ` Randy Brukardt
  1 sibling, 0 replies; 33+ messages in thread
From: Randy Brukardt @ 2013-05-02  2:33 UTC (permalink / raw)


"egilhh" <egilhovik@hotmail.com> wrote in message 
news:c5f03831-5aec-4045-835a-d1fad2ccec5e@googlegroups.com...
...
>whereas 2005 permitted the other behavior. (A language lawyer is needed to
>confirm this)

Sorry, I'm not silly enough to venture into the "Heart of Darkness" without 
an ARG-certified need. :-)

My gut feeling is that nothing should have changed, but the rules in 
7.6.1(11) were so brain-damaged that pretty much anything would have been 
"correct" for anonymous access types. We decided that such 
under-specification was nasty and tied all of this down.

                             Randy.




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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-04-23 17:57     ` Adam Beneschan
  2013-04-25  8:48       ` egilhh
@ 2013-05-02  2:38       ` Randy Brukardt
  2013-05-02 16:15         ` Adam Beneschan
  2013-05-03  1:11         ` Adam Beneschan
  1 sibling, 2 replies; 33+ messages in thread
From: Randy Brukardt @ 2013-05-02  2:38 UTC (permalink / raw)


On Tuesday, April 23, 2013 9:52:04 AM UTC-7, Simon Wright wrote:
>
> > The upshot of all this is that, by 7.6.1(4) and 9.3(2), in Make_ER,
> > the task created by the allocator *depends* *on* the body of Make_ER,
> > and therefore the body of Make_ER cannot complete until the task has
> > completed.  That should be enough to explain the results.
>
> Yes, but there are other similar side effects: in the tests, OP wrote
>
>     declare
> function Make(Input : in String) return not null access Testing
>        renames Make_EF;
>
> P : constant array (Positive range <>) of
>   not null access constant Testing:=
>     ( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
>     begin
>        null;
>     end TEST_1;
>
> and the code doesn't exit the declare block until all the tasks have
> completed.

Adam says:
> I don't see a language reason for that.

I don't understand. The anonymous access type is declared in the block, as 
the master of an access return is that of the point of call [it's passed 
into the function if necessary]. (That's changed in Ada 2012, but the 
previous definition was nonsense.) That's the master of the allocators. So 
of course the tasks "belong" to the master of the block, and the block has 
to wait for them to complete.

BTW, I don't think the extended return should be different, but I have no 
interest in figuring out whether it could or not. It probably depends on 
exactly how/where the allocator is written.

No human can figure these things out, so please don't use them and save the 
brain of an ARG member. ;-)

                                  Randy.


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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-05-02  2:20     ` Randy Brukardt
@ 2013-05-02  4:41       ` Shark8
  0 siblings, 0 replies; 33+ messages in thread
From: Shark8 @ 2013-05-02  4:41 UTC (permalink / raw)


On Wednesday, May 1, 2013 8:20:07 PM UTC-6, Randy Brukardt wrote:
> "Shark8" wrote in message 
> 
> news:e0c67da2-159a-4a37-b199-1d80312f6aca@googlegroups.com...
> ...
> >> Delay
> >> also causes context switching. When you use null statement the main task
> >> likely to manage to create all contestant before any of them gains the
> >> processor (depending on OS settings and number of cores available).
> 
> >I have four cores; that shouldn't be a problem though -- I'm using the 
> >protected
> >object to manage my text-output debugging.
> 
> 
> But doing that is a Bounded_Error (see 9.5.1(8-18), and specifically 
> paragraph 18).

I thought I remembered something about it being questionable/implementation-defined if it would work as expected -- but it did work on the initial experiment (which was actually on tasks w/ discriminants).


> It of course might work as you intend (that's one of the possible results), 

*nod*

> but its something you should avoid in code unless you never, ever expect to 
> run it on a different Ada compiler.

Right.

> To do this correctly, you have to use a lock object, typically wrapped in a 
> controlled object so that initialization does the locking and finalization 
> does the unlocking (that way you don't have to worry about abort or 
> exceptions screwing up your locking). I'll leave the code needed as an 
> exercise for the OP. :-)

I see. I've been putting off getting into finalization... oh, hey, what about tasks as fields of records...

;)


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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-05-02  2:38       ` Randy Brukardt
@ 2013-05-02 16:15         ` Adam Beneschan
  2013-05-02 22:00           ` Randy Brukardt
  2013-05-03  1:11         ` Adam Beneschan
  1 sibling, 1 reply; 33+ messages in thread
From: Adam Beneschan @ 2013-05-02 16:15 UTC (permalink / raw)


On Wednesday, May 1, 2013 7:38:29 PM UTC-7, Randy Brukardt wrote:

> I don't understand. The anonymous access type is declared in the block, as 
> the master of an access return is that of the point of call [it's passed 
> into the function if necessary]. (That's changed in Ada 2012, but the 
> previous definition was nonsense.) That's the master of the allocators.

I think I covered this in my previous response to Egil, but it doesn't appear to me that the RM says this is the master of an allocated task.  That's defined in 9.3(2), which says the master of an allocated task is the master that elaborates the anonymous access type declaration.  Maybe it's the intent that the "anonymous access type declaration" involved here is the one in the block, but there are multiple anonymous access type declarations involved--the one declared with the FUNCTION declaration, and the one declared in the block--and I don't know of any reason in the RM that says the "given access type" is one or the other.  My thinking is that it should be the obvious one--the declaration that is referred to at the point where the allocator occurs, which would be the function result type.

The same problem occurs with extended return:

> BTW, I don't think the extended return should be different, but I have no 
> interest in figuring out whether it could or not. It probably depends on 
> exactly how/where the allocator is written.

The problem is that the extended return introduces yet a third anonymous access type declaration.  Apparently you think that this shouldn't change things, and it makes sense that it shouldn't.  But the way 9.3(2) is written, I think it does.

I think the answer is just that 9.3(2) is broken and needs to be fixed.  It works fine for named access types, but leads to possibly undesirable consequences with anonymous access types.  In fact, this rule essentially hasn't changed since Ada 83 (RM83 9.4(2)), when of course there were no anonymous access types.  Either 9.3(2) needs to be rewritten to specify exactly what is supposed to happen when an allocator for an anonymous access type creates a task, or it should just be illegal to use an allocator for an anonymous-access-to-task (or to a type containing a task).  I wouldn't be opposed to the latter alternative.  It wouldn't be backward compatible, but at least it would accomplish this purpose:

> No human can figure these things out, so please don't use them and save the 
> brain of an ARG member. ;-)

                                  -- Adam



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-05-02  2:28   ` Randy Brukardt
@ 2013-05-02 16:37     ` Adam Beneschan
  0 siblings, 0 replies; 33+ messages in thread
From: Adam Beneschan @ 2013-05-02 16:37 UTC (permalink / raw)


On Wednesday, May 1, 2013 7:28:38 PM UTC-7, Randy Brukardt wrote:

> >The language here may be a bit sloppy, since for an anonymous access
> >type, I'm not sure there's any such thing as "the declaration of
> >... [a] given access type".
> 
> Wow, I think we've missed this Adam for a while! I'm pretty sure there is 
> wording somewhere that says that where an anonymous access type is declared, 

Well, 3.1(5) says "A declaration is a language construct that associates a name with (a view of) an entity".  But for an anonymous access type, there's no name.  
So based on that, there's no declaration.  (If there were some other language that indicated what the "declaration" of an anonymous access type is, I'd expect to find it in 3.10, but I don't see it there.)

I think this just bolsters my view that 9.3(2), which was pretty much written when there were no anonymous access types, needs updating.

                             -- Adam



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-05-02 16:15         ` Adam Beneschan
@ 2013-05-02 22:00           ` Randy Brukardt
  0 siblings, 0 replies; 33+ messages in thread
From: Randy Brukardt @ 2013-05-02 22:00 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:76761472-73ab-4869-a214-5945e9cc4a77@googlegroups.com...
...
>I think the answer is just that 9.3(2) is broken and needs to be fixed.

I agree, but not for the reason that you give. :-)

Anyway, since you posted this on Ada-Comment, I'll respond properly there.

                                Randy. 


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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-05-02  2:38       ` Randy Brukardt
  2013-05-02 16:15         ` Adam Beneschan
@ 2013-05-03  1:11         ` Adam Beneschan
  2013-05-03  5:34           ` Simon Wright
                             ` (2 more replies)
  1 sibling, 3 replies; 33+ messages in thread
From: Adam Beneschan @ 2013-05-03  1:11 UTC (permalink / raw)


On Wednesday, May 1, 2013 7:38:29 PM UTC-7, Randy Brukardt wrote:
> On Tuesday, April 23, 2013 9:52:04 AM UTC-7, Simon Wright wrote:

> 
> > Yes, but there are other similar side effects: in the tests, OP wrote
> 
> > declare
> > function Make(Input : in String) return not null access Testing
> >        renames Make_EF;
> >
> > P : constant array (Positive range <>) of
> >   not null access constant Testing:=
> >     ( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
> > begin
> >        null;
> > end TEST_1;
> 
> > and the code doesn't exit the declare block until all the tasks have
> > completed.
> 
> Adam says:
> > I don't see a language reason for that.

OK, after some discussion on Ada-Comment (mostly me being straightened out by Randy), I've found out what the intent of the rules was supposed to be.  I didn't really understand them before.  The RM defines accessibility levels, which correspond with masters; the intent was that when a task is allocated using an anonymous access type, the master on which the task depends is supposed to be the master "corresponding" with the accessibility level (9.3(2) isn't clear about this, but that was the intent).  And (as Egil pointed out) the accessibility level of anonymous access function results has been changed in Ada 2012--it now gets its level from the point where the function is called.  So that explains the behavior.

Based on what I now understand, I think Shark8's original example is misbehaving.  6.5(5.3) says that the accessibility level of an anonymous-access in an extended return statement is the same as the accessibility level of the function result; and since this seems to determine what masters the allocated tasks depend on, the master for the task allocated by Make_ER should be the same as the one in Make_NR and (I think) for Make_EF.  So it's a compiler bug that they're behaving differently.

I still think that anonymous access types should only be used when necessary, since there are special accessibility level rules for anonymous access types that have some surprising consequences.  There may be cases where it's beneficial to take advantage of those special rules.  But one should not use anonymous access types just because "hey, Ada lets us do it now and I can just throw in a pointer without having to think up a type name, like C programmers get to do!".  A good rule might be "don't use anonymous access types unless you've read 3.10.2 and understand it thoroughly."  (OK, that was a joke.)

                                -- Adam


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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-05-03  1:11         ` Adam Beneschan
@ 2013-05-03  5:34           ` Simon Wright
  2013-05-03  6:43           ` egilhh
  2013-05-03 23:09           ` Randy Brukardt
  2 siblings, 0 replies; 33+ messages in thread
From: Simon Wright @ 2013-05-03  5:34 UTC (permalink / raw)


Adam Beneschan <adam@irvine.com> writes:

> I still think that anonymous access types should only be used when
> necessary, since there are special accessibility level rules for
> anonymous access types that have some surprising consequences.  There
> may be cases where it's beneficial to take advantage of those special
> rules.  But one should not use anonymous access types just because
> "hey, Ada lets us do it now and I can just throw in a pointer without
> having to think up a type name, like C programmers get to do!".  A
> good rule might be "don't use anonymous access types unless you've
> read 3.10.2 and understand it thoroughly."  (OK, that was a joke.)

This sounds like wise advice, that should go into a style guide.


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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-05-03  1:11         ` Adam Beneschan
  2013-05-03  5:34           ` Simon Wright
@ 2013-05-03  6:43           ` egilhh
  2013-05-03 16:49             ` Adam Beneschan
  2013-05-03 23:09           ` Randy Brukardt
  2 siblings, 1 reply; 33+ messages in thread
From: egilhh @ 2013-05-03  6:43 UTC (permalink / raw)


On Friday, May 3, 2013 3:11:35 AM UTC+2, Adam Beneschan wrote:
> > 
> Based on what I now understand, I think Shark8's original example is misbehaving.  6.5(5.3) says that the accessibility level of an anonymous-access in an extended return statement is the same as the accessibility level of the function result; and since this seems to determine what masters the allocated tasks depend on, the master for the task allocated by Make_ER should be the same as the one in Make_NR and (I think) for Make_EF.  So it's a compiler bug that they're behaving differently.
> 

But 6.5(5.11/3) says that for extended return, a new nominal subtype is created
for the return object, which seems to be different from the function result
subtype.

But then, 6.5(7/2): "If the return object has any parts that are tasks, the activation of those tasks does not occur until after the function returns"


Easy to get confused here, but I think 6.5(7/2) is (or at least should be)
the winner :)


-- 
~egilhh



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-05-03  6:43           ` egilhh
@ 2013-05-03 16:49             ` Adam Beneschan
  0 siblings, 0 replies; 33+ messages in thread
From: Adam Beneschan @ 2013-05-03 16:49 UTC (permalink / raw)


On Thursday, May 2, 2013 11:43:16 PM UTC-7, egilhh wrote:
> On Friday, May 3, 2013 3:11:35 AM UTC+2, Adam Beneschan wrote:
> 
> > > 
> 
> > Based on what I now understand, I think Shark8's original example is misbehaving.  6.5(5.3) says that the accessibility level of an anonymous-access in an extended return statement is the same as the accessibility level of the function result; and since this seems to determine what masters the allocated tasks depend on, the master for the task allocated by Make_ER should be the same as the one in Make_NR and (I think) for Make_EF.  So it's a compiler bug that they're behaving differently.
> 
> 
> But 6.5(5.11/3) says that for extended return, a new nominal subtype is created
> for the return object, which seems to be different from the function result
> subtype.

The "subtype" here isn't relevant.  The *type* is different only because it's an anonymous access type, and each appearance of an anonymous access type creates a new type.  But objects of anonymous access types tend to convert from one to another implicitly, so that isn't really relevant either.  The important thing seems to be what the accessibility levels of the types are, and 6.5(5.3) is what makes the big difference here.

 
> But then, 6.5(7/2): "If the return object has any parts that are tasks, the activation of those tasks does not occur until after the function returns"

The return object is of an access type, so it doesn't have any task parts.  The thing that the access type *points* to isn't the return object.  

                         -- Adam



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

* Re: Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
  2013-05-03  1:11         ` Adam Beneschan
  2013-05-03  5:34           ` Simon Wright
  2013-05-03  6:43           ` egilhh
@ 2013-05-03 23:09           ` Randy Brukardt
  2 siblings, 0 replies; 33+ messages in thread
From: Randy Brukardt @ 2013-05-03 23:09 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:e7ef987b-3fdb-4b59-bfd5-918006cf1ce2@googlegroups.com...
...
>I still think that anonymous access types should only be used when 
>necessary,
>since there are special accessibility level rules for anonymous access 
>types that
>have some surprising consequences.  There may be cases where it's 
>beneficial
>to take advantage of those special rules.

It might be useful to know that the accessibility of an anonymous access 
return type is the same as that of an access discriminant returned from a 
function. And this is what provides the "value" of these things: the 
user-defined dereferencing is built on access discriminants simply because 
they already had the correct accessibility. So we were able to get what we 
wanted (a very short-lived access value that can be dereferenced but cannot 
be copied in most circumstances) without inventing new rules.

This is where we put up the disclaimer (a-la Mythbusters): "Do not try this 
at home! The ARG are trained professionals and they barely know what they're 
doing! :-)"

> But one should not use anonymous access types just because "hey, Ada
>lets us do it now and I can just throw in a pointer without having to think 
>up
>a type name, like C programmers get to do!".  A good rule might be "don't 
>use
>anonymous access types unless you've read 3.10.2 and understand it 
>thoroughly."
>(OK, that was a joke.)

This is generally good advice. There are a lot of different kinds of 
anonymous access types and they all act different; unless you know what your 
doing, you're going to get it wrong. For instance, the anonymous access type 
(AAT) of a component has the accessibility of the enclosing type (usually 
static); AAT of parameters is fully dynamic; AAT of a stand-alone object is 
almost fully dynamic (they don't allow shorter lifetimes), AAT of a function 
result depends on the point of call, and AAT of a discriminant depends on 
where it is used, including all of the above.

There is a good reason that 3.10.2 is known within the ARG as the "Heart of 
Darkness". :-) [This is now mentioned in the AARM: 3.10.2(3.b/3).]

                                               Randy.


                                -- Adam






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

end of thread, other threads:[~2013-05-03 23:09 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-22 18:27 Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns Shark8
2013-04-22 19:13 ` Dmitry A. Kazakov
2013-04-22 20:11   ` Shark8
2013-04-23  6:15     ` Simon Wright
2013-04-23  7:35     ` Stephen Leake
2013-04-23  8:58     ` Dmitry A. Kazakov
2013-05-02  2:20     ` Randy Brukardt
2013-05-02  4:41       ` Shark8
2013-04-23  6:32 ` egilhh
2013-04-23 15:24   ` Adam Beneschan
2013-04-24  5:56     ` egilhh
2013-04-24 14:40       ` Adam Beneschan
2013-04-25  5:30         ` egilhh
2013-04-25  5:41           ` Shark8
2013-04-23 16:00 ` Adam Beneschan
2013-04-23 16:52   ` Simon Wright
2013-04-23 17:57     ` Adam Beneschan
2013-04-25  8:48       ` egilhh
2013-04-25 15:19         ` Adam Beneschan
2013-05-02  2:33         ` Randy Brukardt
2013-05-02  2:38       ` Randy Brukardt
2013-05-02 16:15         ` Adam Beneschan
2013-05-02 22:00           ` Randy Brukardt
2013-05-03  1:11         ` Adam Beneschan
2013-05-03  5:34           ` Simon Wright
2013-05-03  6:43           ` egilhh
2013-05-03 16:49             ` Adam Beneschan
2013-05-03 23:09           ` Randy Brukardt
2013-04-23 23:00     ` Shark8
2013-04-23 23:16       ` Adam Beneschan
2013-05-02  2:28   ` Randy Brukardt
2013-05-02 16:37     ` Adam Beneschan
2013-04-23 16:33 ` Simon Wright

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