comp.lang.ada
 help / color / mirror / Atom feed
* Protected Type compiler complaint
@ 2014-07-07  7:15 NiGHTS
  2014-07-07  7:55 ` Simon Wright
  2014-07-07 19:06 ` framefritti
  0 siblings, 2 replies; 10+ messages in thread
From: NiGHTS @ 2014-07-07  7:15 UTC (permalink / raw)


Subject: Protected Type compiler complaint
Platform: Linux (Kubuntu 14.04 32-bit)
Dev: GPS 5.0-16, GNAT 4.6


I am new to Ada and GPS so forgive me if my question seems silly. I have tried searching for the answer from various places for hours but for the life of me I can't even find a hint.

I have a very simple project in GPS with a "main" package and a "test" protected type. They occupy files with the same name and adb/ads extensions.

After creating my test files I went to the Menu "Project" -> "Edit Project Properties" -> "Source Files" tab. Then I added the test.adb & test.ads files where my protected type declarations are located. 

When I compile it complains that "protected declaration cannot be used as compilation unit" on line 1 of test.ads. So I remove those files from the project source files options menu. Then when I compile again it complains about "test.ads not found" on line 3 of main.adb.

Here is a summarized view of what my test.ads looks like:

   protected type Test is
       procedure DoSomething;
   end Test;

And here is a summarized view of what my main.adb looks like:

   with Test; use Test;

   procedure main is
   begin
       Test.DoSomething;
   end;

Any ideas what I might be doing wrong?


Thank you in advance for your help!

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

* Re: Protected Type compiler complaint
  2014-07-07  7:15 Protected Type compiler complaint NiGHTS
@ 2014-07-07  7:55 ` Simon Wright
  2014-07-07 14:23   ` NiGHTS
  2014-07-07 19:06 ` framefritti
  1 sibling, 1 reply; 10+ messages in thread
From: Simon Wright @ 2014-07-07  7:55 UTC (permalink / raw)


NiGHTS <nights@unku.us> writes:

> When I compile it complains that "protected declaration cannot be used
> as compilation unit" on line 1 of test.ads. So I remove those files
> from the project source files options menu. Then when I compile again
> it complains about "test.ads not found" on line 3 of main.adb.

A protected declaration cannot be used as a compilation unit; it has to
be declared within one.

> Here is a summarized view of what my test.ads looks like:
>
>    protected type Test is procedure DoSomething; end Test;

   package Test is
      protected type P is
        procedure Do_Something;
      end P;
   end Test;

> And here is a summarized view of what my main.adb looks like:
>
>    with Test; use Test;
>
>    procedure main is begin Test.DoSomething; end;

You made Test a protected *type* (and I've suggested Test.P), so you
need to declare a protected *object* of that type.

   with Test;
   procedure Main is
      O : Test.P;
   begin
      O.Do_Something;
   end Main;


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

* Re: Protected Type compiler complaint
  2014-07-07  7:55 ` Simon Wright
@ 2014-07-07 14:23   ` NiGHTS
  2014-07-07 16:37     ` Adam Beneschan
                       ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: NiGHTS @ 2014-07-07 14:23 UTC (permalink / raw)


On Monday, July 7, 2014 3:55:24 AM UTC-4, Simon Wright wrote:

> > When I compile it complains that "protected declaration cannot be used
> 
> > as compilation unit" on line 1 of test.ads. So I remove those files
> 
> > from the project source files options menu. Then when I compile again
> 
> > it complains about "test.ads not found" on line 3 of main.adb.
> 
> 
> 
> A protected declaration cannot be used as a compilation unit; it has to
> 
> be declared within one.
> 
> 
> 
> > Here is a summarized view of what my test.ads looks like:
> 
> >
> 
> >    protected type Test is procedure DoSomething; end Test;
> 
> 
> 
>    package Test is
> 
>       protected type P is
> 
>         procedure Do_Something;
> 
>       end P;
> 
>    end Test;
> 
> 
> 
> > And here is a summarized view of what my main.adb looks like:
> 
> >
> 
> >    with Test; use Test;
> 
> >
> 
> >    procedure main is begin Test.DoSomething; end;
> 
> 
> 
> You made Test a protected *type* (and I've suggested Test.P), so you
> 
> need to declare a protected *object* of that type.
> 
> 
> 
>    with Test;
> 
>    procedure Main is
> 
>       O : Test.P;
> 
>    begin
> 
>       O.Do_Something;
> 
>    end Main;

Thank you for your help. This makes sense. 

A question about the variables in the Test.P type you introduced. I would like to make available to other spawned tasks these protected variables, so essentially Test.P needs to be a global of some kind with static data in the currently running process. I heard much about not creating global variables for good Ada coding practice, so how is this protected package variables expected to be usable by these spawned tasks? 

NOTE: The task code may not be directly associated to the main package as I expect to create task utility packages shared by multiple applications.


Thank you again for your help.


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

* Re: Protected Type compiler complaint
  2014-07-07 14:23   ` NiGHTS
@ 2014-07-07 16:37     ` Adam Beneschan
  2014-07-07 17:21     ` Simon Wright
  2014-07-08 17:03     ` Shark8
  2 siblings, 0 replies; 10+ messages in thread
From: Adam Beneschan @ 2014-07-07 16:37 UTC (permalink / raw)


On Monday, July 7, 2014 7:23:32 AM UTC-7, NiGHTS wrote:
> On Monday, July 7, 2014 3:55:24 AM UTC-4, Simon Wright wrote:
> 

> A question about the variables in the Test.P type you introduced. I would like to make available to other spawned tasks these protected variables, so essentially Test.P needs to be a global of some kind

Test.P is a type, so it doesn't make sense to be global.  I assume that you want some global *object* whose type is Test.P.

> with static data in the currently running process. I heard much about not creating global variables for good Ada coding practice, so how is this protected package variables expected to be usable by these spawned tasks? 

Global variables are considered poor programming practice in any language--it has nothing to do with Ada.  Understanding the reasons involves getting into software design principles.  I did a quick search and found what seems to be a pretty good discussion at http://programmers.stackexchange.com/questions/148108/why-is-global-state-so-evil.

Anyway, I don't see that your protected object *needs* to be a global variable.  If you have some state that you want to share between tasks, you can either declare an access to your protected type, or declare a record type that contains other state information (including the protected object) and an access to that.  Then there are ways to get an access-to-protected or access-to-record passed to each task (one is to use an accept statement to pass the access value to a task; another is to declare the task type with an access discriminant).  

However, this can be a problem if the tasks are standalone top-level tasks that are not explicitly created by the program.  It's possible that this would be one case where a global variable is less bad than the alternatives, but you should definitely try to understand *why* globals are considered poor practice so that you understand what problems you might cause by using them.

                           -- Adam 

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

* Re: Protected Type compiler complaint
  2014-07-07 14:23   ` NiGHTS
  2014-07-07 16:37     ` Adam Beneschan
@ 2014-07-07 17:21     ` Simon Wright
  2014-07-08 17:03     ` Shark8
  2 siblings, 0 replies; 10+ messages in thread
From: Simon Wright @ 2014-07-07 17:21 UTC (permalink / raw)


NiGHTS <nights@unku.us> writes:

> I would like to make available to other spawned tasks these protected
> variables, so essentially Test.P needs to be a global of some kind
> with static data in the currently running process. I heard much about
> not creating global variables for good Ada coding practice, so how is
> this protected package variables expected to be usable by these
> spawned tasks?

As Adam says, an instance of Test.P.

   with Test;
   package Globals is
      O : Test.P;
   end Globals;

will make the instance globally visible, and any of your packages can
then call Globals.O.DoSomething, obtaining protected access to the
private variables of O.

Whether it's good coding practice to do this is a different question;
but at least you'll have safe access to O's content.

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

* Re: Protected Type compiler complaint
  2014-07-07  7:15 Protected Type compiler complaint NiGHTS
  2014-07-07  7:55 ` Simon Wright
@ 2014-07-07 19:06 ` framefritti
  2014-07-08  7:11   ` Georg Bauhaus
  2014-07-08  7:53   ` Dmitry A. Kazakov
  1 sibling, 2 replies; 10+ messages in thread
From: framefritti @ 2014-07-07 19:06 UTC (permalink / raw)


In my humble and "gut" opinion, maybe in this case the use of a global object is not as bad as in other cases since by its own nature a protected object acts as a communication mean between different tasks, so it is "natural" that it must be visible to "everyone" (although you could partially restrict its visibility by placing it inside a suitable child package). Moreover, protected object have implicitly some kind of "high level" interface, so that its access is somehow controlled.

Riccardo




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

* Re: Protected Type compiler complaint
  2014-07-07 19:06 ` framefritti
@ 2014-07-08  7:11   ` Georg Bauhaus
  2014-07-08  7:53   ` Dmitry A. Kazakov
  1 sibling, 0 replies; 10+ messages in thread
From: Georg Bauhaus @ 2014-07-08  7:11 UTC (permalink / raw)


On 07.07.14 21:06, framefritti wrote:
> by its own nature a protected object acts as a communication mean between different tasks, so it is "natural" that it must be visible to "everyone" (although you could partially restrict its visibility by placing it inside a suitable child package).

By the nature of communication, a protected object used as a means
of communication just needs to be visible where needed. Its type
may be more global.
If tasks are started from within a subprogram doing auxiliary work
not useful anywhere else, chances are that their definition profits
from being local to the subprogram, possibly referring to local items.
Then there is no need that some PO exist outside the subprogram:

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

* Re: Protected Type compiler complaint
  2014-07-07 19:06 ` framefritti
  2014-07-08  7:11   ` Georg Bauhaus
@ 2014-07-08  7:53   ` Dmitry A. Kazakov
  1 sibling, 0 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2014-07-08  7:53 UTC (permalink / raw)


On Mon, 07 Jul 2014 14:06:53 -0500, framefritti wrote:

> In my humble and "gut" opinion, maybe in this case the use of a global
> object is not as bad as in other cases since by its own nature a protected
> object acts as a communication mean between different tasks, so it is
> "natural" that it must be visible to "everyone" (although you could
> partially restrict its visibility by placing it inside a suitable child
> package). 

That mixes tasks with modules and modules with scopes.

> Moreover, protected object have implicitly some kind of "high
> level" interface, so that its access is somehow controlled.

It is rather the semantics of the access. The interface is same - operation
calls. (Ada even tried some feeble kind of unifying "protected" and "plain"
interfaces.)

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


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

* Re: Protected Type compiler complaint
  2014-07-07 14:23   ` NiGHTS
  2014-07-07 16:37     ` Adam Beneschan
  2014-07-07 17:21     ` Simon Wright
@ 2014-07-08 17:03     ` Shark8
  2014-07-08 17:50       ` Anh Vo
  2 siblings, 1 reply; 10+ messages in thread
From: Shark8 @ 2014-07-08 17:03 UTC (permalink / raw)


On 07-Jul-14 08:23, NiGHTS wrote:
> A question about the variables in the Test.P type you introduced.
> I would like to make available to other spawned tasks these protected
> variables, so essentially Test.P needs to be a global of some kind
> with static data in the currently running process.

Not necessarily; you could use an access-discriminated task for these 
spawned tasks.

Assuming:

    package Test is
       protected type P is
         procedure Do_Something;
       end P;
    end Test;

We can do this:

    with Test;
    package Processes is
       task type K(P : not null access Test.P) is
             entry x( Input  : in  Integer );
             entry y( Output : out Integer );
       End K;
    End Processes;

This will allow you to access the protected object you specify when you 
declare the task; an example usage would be:

    with
      Test,
      Processes;
    procedure Main is
       O : Aliased Test.P;
       J : Processes.K(O'Access);
       K : Integer;
    begin
       -- O.Do_Something;
       J.Y(K); -- calls O.do_something internally.
    end Main;


------------
-- Bodies --
------------

    package body Test is
       protected body P is
             procedure Do_Something is
             begin
                 Ada.Text_IO.Put_Line("Did Something!");
             End Do_Something;
       end P;
    end Test;


    package body Processes is
         task body K is
             Value : Integer:= 0;
         begin
             loop
                 select
                     accept x (Input : in Integer) do
                         Value:= Value + Input;
                     end x;
                 or
                     accept y (Output : out Integer) do
                         Output:= Value;
                         Value:= 0;
                         P.Do_Something;
                     end y;
                 or
                     terminate;
                 end select;
             end loop;
       End K;
    End Processes;


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

* Re: Protected Type compiler complaint
  2014-07-08 17:03     ` Shark8
@ 2014-07-08 17:50       ` Anh Vo
  0 siblings, 0 replies; 10+ messages in thread
From: Anh Vo @ 2014-07-08 17:50 UTC (permalink / raw)


On Tuesday, July 8, 2014 10:03:31 AM UTC-7, Shark8 wrote:
> On 07-Jul-14 08:23, NiGHTS wrote:
> > A question about the variables in the Test.P type you introduced. 
> > I would like to make available to other spawned tasks these protected 
> > variables, so essentially Test.P needs to be a global of some kind 
> > with static data in the currently running process. 
> 
> Not necessarily; you could use an access-discriminated task for these  
> spawned tasks.

The term spawned tasks makes me think low level OS tasks are involved here. Actually, it is just a regular Ada task. Thus, I would simply call it task(s) :-)



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

end of thread, other threads:[~2014-07-08 17:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-07  7:15 Protected Type compiler complaint NiGHTS
2014-07-07  7:55 ` Simon Wright
2014-07-07 14:23   ` NiGHTS
2014-07-07 16:37     ` Adam Beneschan
2014-07-07 17:21     ` Simon Wright
2014-07-08 17:03     ` Shark8
2014-07-08 17:50       ` Anh Vo
2014-07-07 19:06 ` framefritti
2014-07-08  7:11   ` Georg Bauhaus
2014-07-08  7:53   ` Dmitry A. Kazakov

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