comp.lang.ada
 help / color / mirror / Atom feed
* limited /non-limited tagged type
@ 2011-03-04 18:56 Hacid
  2011-03-04 19:54 ` Edward Fish
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Hacid @ 2011-03-04 18:56 UTC (permalink / raw)


Hi,

I haven't found an existing topic about this, so I ask my question :

I develop a package for colleagues. In this package I define a tagged
type. I want to prevent them from doing assignments on this type. But
I want to be able to do these assignments in my body.

I understand why I can't define my type limited in the public part and
not limited in the private part. But is there a way to do what I
want ?

Something like :

package Foo is

   type Object is tagged private;

   function ":=" (Left : out Object,; Right : in Object) is abstract;
-- I know this looks strange

end Foo;

Thanks.



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

* Re: limited /non-limited tagged type
  2011-03-04 18:56 limited /non-limited tagged type Hacid
@ 2011-03-04 19:54 ` Edward Fish
  2011-03-04 21:18   ` Hacid
  2011-03-04 20:10 ` Georg Bauhaus
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Edward Fish @ 2011-03-04 19:54 UTC (permalink / raw)


On Mar 4, 11:56 am, Hacid <chadi.alku...@gmail.com> wrote:
> Hi,
>
> I haven't found an existing topic about this, so I ask my question :
>
> I develop a package for colleagues. In this package I define a tagged
> type. I want to prevent them from doing assignments on this type. But
> I want to be able to do these assignments in my body.
>
> I understand why I can't define my type limited in the public part and
> not limited in the private part. But is there a way to do what I
> want ?
>
> Something like :
>
> package Foo is
>
>    type Object is tagged private;
>
>    function ":=" (Left : out Object,; Right : in Object) is abstract;
> -- I know this looks strange
>
> end Foo;
>
> Thanks.

Yes, I think.
You could add in an 'indirection step'.

Package Whatever is
Type Public_Type is limited private tagged;
--primitive functions.

Private
  - Base is the type that you will manipulate in the Body.
  Type Base is tagged record
    -- fields
Null;
   End Record;

Type Public_Type is Base with null record;

End Whatever;



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

* Re: limited /non-limited tagged type
  2011-03-04 18:56 limited /non-limited tagged type Hacid
  2011-03-04 19:54 ` Edward Fish
@ 2011-03-04 20:10 ` Georg Bauhaus
  2011-03-04 21:55   ` Hacid
  2011-03-04 23:34 ` Adam Beneschan
  2011-03-05  3:26 ` Adam Beneschan
  3 siblings, 1 reply; 14+ messages in thread
From: Georg Bauhaus @ 2011-03-04 20:10 UTC (permalink / raw)


On 3/4/11 7:56 PM, Hacid wrote:

> I understand why I can't define my type limited in the public part and
> not limited in the private part. But is there a way to do what I
> want ?
>
> Something like :
>
> package Foo is
>
>     type Object is tagged private;
>
>     function ":=" (Left : out Object,; Right : in Object) is abstract;
> -- I know this looks strange
>
> end Foo;

Maybe something along these lines?

package Foo_3 is

     type Object is tagged limited private;

private

     type Wrapped is record
         null;  -- ...
     end record;

     procedure Copy_Constructor
         (Source :  in Object;
          Target : out Object );

     type Object is tagged limited
         record
             Data : Wrapped;
         end record;

end Foo_3;

package body Foo_3 is

     procedure Copy_Constructor
         (Source :  in Object;
          Target : out Object )
     is
     begin
         Target.Data := Source.Data;
     end Copy_Constructor;

end Foo_3;



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

* Re: limited /non-limited tagged type
  2011-03-04 19:54 ` Edward Fish
@ 2011-03-04 21:18   ` Hacid
  2011-03-05  0:17     ` Edward Fish
  0 siblings, 1 reply; 14+ messages in thread
From: Hacid @ 2011-03-04 21:18 UTC (permalink / raw)


On 4 mar, 20:54, Edward Fish <edward.r.f...@gmail.com> wrote:
> On Mar 4, 11:56 am, Hacid <chadi.alku...@gmail.com> wrote:
>
>
>
> > Hi,
>
> > I haven't found an existing topic about this, so I ask my question :
>
> > I develop a package for colleagues. In this package I define a tagged
> > type. I want to prevent them from doing assignments on this type. But
> > I want to be able to do these assignments in my body.
>
> > I understand why I can't define my type limited in the public part and
> > not limited in the private part. But is there a way to do what I
> > want ?
>
> > Something like :
>
> > package Foo is
>
> >    type Object is tagged private;
>
> >    function ":=" (Left : out Object,; Right : in Object) is abstract;
> > -- I know this looks strange
>
> > end Foo;
>
> > Thanks.
>
> Yes, I think.
> You could add in an 'indirection step'.
>

--
package Whatever is

   type Public_Type is tagged limited private;

   --primitive functions.

private

  -- Base is the type that you will manipulate in the Body.
  type Base is tagged record
    -- fields
     null;
  end record;

  type Public_Type is new Base with null record;

end Whatever;
--
whatever.ads:15:08: completion of limited tagged type must be limited

This way seems to not work ... :o(



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

* Re: limited /non-limited tagged type
  2011-03-04 20:10 ` Georg Bauhaus
@ 2011-03-04 21:55   ` Hacid
  2011-03-04 22:21     ` Hacid
  2011-03-04 22:22     ` Georg Bauhaus
  0 siblings, 2 replies; 14+ messages in thread
From: Hacid @ 2011-03-04 21:55 UTC (permalink / raw)


On 4 mar, 21:10, Georg Bauhaus <rm-host.bauh...@maps.futureapps.de>
wrote:
> On 3/4/11 7:56 PM, Hacid wrote:
>
> > I understand why I can't define my type limited in the public part and
> > not limited in the private part. But is there a way to do what I
> > want ?
>
> > Something like :
>
> > package Foo is
>
> >     type Object is tagged private;
>
> >     function ":=" (Left : out Object,; Right : in Object) is abstract;
> > -- I know this looks strange
>
> > end Foo;
>
> Maybe something along these lines?
>
> package Foo_3 is
>
>      type Object is tagged limited private;
>
> private
>
>      type Wrapped is record
>          null;  -- ...
>      end record;
>
>      procedure Copy_Constructor
>          (Source :  in Object;
>           Target : out Object );
>
>      type Object is tagged limited
>          record
>              Data : Wrapped;
>          end record;
>
> end Foo_3;
>
> package body Foo_3 is
>
>      procedure Copy_Constructor
>          (Source :  in Object;
>           Target : out Object )
>      is
>      begin
>          Target.Data := Source.Data;
>      end Copy_Constructor;
>
> end Foo_3;

This solution works but if I extend my package with some addons, I am
blocked :

generic
   type Element is new Object with private;
package Foo_3.Pools is

   type Pool is limited private;
   -- Some services

   procedure Copy (From : in Pool; To : out Pool);

private

   type Pool is array (1 .. 1_000) of Element;

end Foo_3.Pools;
--
package body Foo_3.Pools is

   procedure Copy (From : in Pool; To : out Pool) is
   begin
      for I in To'Range loop
         Copy (From => From (I), To => To (I));
         -- This call copy just a part of Element !!!
      end loop;
   end Copy;

end Foo_3.Pools;

Do you see how to resolve this second problem ?

Thanks.




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

* Re: limited /non-limited tagged type
  2011-03-04 21:55   ` Hacid
@ 2011-03-04 22:21     ` Hacid
  2011-03-05  1:20       ` Randy Brukardt
  2011-03-04 22:22     ` Georg Bauhaus
  1 sibling, 1 reply; 14+ messages in thread
From: Hacid @ 2011-03-04 22:21 UTC (permalink / raw)


To explain in other words my problem :
I want to control type assignment but :
 1) I can't use Ada.Limited_Controlled because I have a ZFP Run Time
 2) I can't use limited tagged type because I need to perform array
copies of derivated type
 3) I can't just say "Do not use assignment" because without checks
they will do

So I was hoping that Ada have a construct to solve this problem...
But maybe a rule checker is the best way  :o(



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

* Re: limited /non-limited tagged type
  2011-03-04 21:55   ` Hacid
  2011-03-04 22:21     ` Hacid
@ 2011-03-04 22:22     ` Georg Bauhaus
  2011-03-04 22:40       ` Hacid
  1 sibling, 1 reply; 14+ messages in thread
From: Georg Bauhaus @ 2011-03-04 22:22 UTC (permalink / raw)


On 3/4/11 10:55 PM, Hacid wrote:

> This solution works but if I extend my package with some addons, I am
> blocked :
>
> generic
>     type Element is new Object with private;
> package Foo_3.Pools is

Type Element is like type Object WRT visibility of the Copy
operation.  The formal is public here, hence there is no
visible operation Copy, since that operation is private.

If you need the Copy operation in the package only, you
can make Foo_3.Pools a private child, thus

private generic
    type Element is new Object with private;
package Foo_3.Pools is

Foo_3.Copy can then effectively be called from within
Foo_3.Pools.Copy.



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

* Re: limited /non-limited tagged type
  2011-03-04 22:22     ` Georg Bauhaus
@ 2011-03-04 22:40       ` Hacid
  2011-03-05  1:29         ` Georg Bauhaus
  0 siblings, 1 reply; 14+ messages in thread
From: Hacid @ 2011-03-04 22:40 UTC (permalink / raw)


On 4 mar, 23:22, Georg Bauhaus <rm-host.bauh...@maps.futureapps.de>
wrote:
> On 3/4/11 10:55 PM, Hacid wrote:
>
> > This solution works but if I extend my package with some addons, I am
> > blocked :
>
> > generic
> >     type Element is new Object with private;
> > package Foo_3.Pools is
>
> Type Element is like type Object WRT visibility of the Copy
> operation.  The formal is public here, hence there is no
> visible operation Copy, since that operation is private.
>
> If you need the Copy operation in the package only, you
> can make Foo_3.Pools a private child, thus
>
> private generic
>     type Element is new Object with private;
> package Foo_3.Pools is
>
> Foo_3.Copy can then effectively be called from within
> Foo_3.Pools.Copy.


I have no compilation error on my file foo_3-pools.adb.
But this construction make only a partial copy of the derivated
element.
And I would want a full one. That was what I tried to explain...but I
am not very understandable in English :o)



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

* Re: limited /non-limited tagged type
  2011-03-04 18:56 limited /non-limited tagged type Hacid
  2011-03-04 19:54 ` Edward Fish
  2011-03-04 20:10 ` Georg Bauhaus
@ 2011-03-04 23:34 ` Adam Beneschan
  2011-03-05  3:26 ` Adam Beneschan
  3 siblings, 0 replies; 14+ messages in thread
From: Adam Beneschan @ 2011-03-04 23:34 UTC (permalink / raw)


On Mar 4, 10:56 am, Hacid <chadi.alku...@gmail.com> wrote:
> Hi,
>
> I haven't found an existing topic about this, so I ask my question :
>
> I develop a package for colleagues. In this package I define a tagged
> type. I want to prevent them from doing assignments on this type. But
> I want to be able to do these assignments in my body.
>
> I understand why I can't define my type limited in the public part and
> not limited in the private part. But is there a way to do what I
> want ?
>
> Something like :
>
> package Foo is
>
>    type Object is tagged private;
>
>    function ":=" (Left : out Object,; Right : in Object) is abstract;
> -- I know this looks strange
>
> end Foo;
>
> Thanks.

I think we might need a little more information ...

First of all, why does Object have to be visibly tagged?  That is, why
do users of the package Foo need to see Object as tagged?  I presume
that this is because you want those users to be able to declare type
extensions of Object.  (If not, you can just declare Object as
"limited private" and make the full view tagged and non-limited.)

OK, so you want a user to be able to declare their own type extension:

   type Another_Object is new Foo.Object with record ... end record;

The next question is, why do you need to assign Objects in the body of
Foo?  If this is to implement some operation in Foo:

   package Foo is
      type Object is tagged private;
      procedure Operation (X : in out Object...);

or something like that, then perhaps you want Operation to be able to
do an assignment operation.  Here's the problem: When the user
declares Another_Object, won't they probably need to declare an
overriding version of Operation?  And if part of Operation's purpose
involves assignment, then wouldn't the overriding version of Operation
also need to do assignment, in order to carry out its purpose?  But
you've said that you want to prevent assignment.

Basically, I'm having trouble seeing how this could be the real
problem.  That is, even if you could declare a non-limited tagged type
and remove the ":=" operation, in all probability I think you're going
to realize that there are other problems with your design.  I could be
wrong.  If you can explain what you're trying to accomplish, that
might help point us to a solution.

                              -- Adam



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

* Re: limited /non-limited tagged type
  2011-03-04 21:18   ` Hacid
@ 2011-03-05  0:17     ` Edward Fish
  0 siblings, 0 replies; 14+ messages in thread
From: Edward Fish @ 2011-03-05  0:17 UTC (permalink / raw)


On Mar 4, 2:18 pm, Hacid <chadi.alku...@gmail.com> wrote:
> On 4 mar, 20:54, Edward Fish <edward.r.f...@gmail.com> wrote:
>
>
>
> > On Mar 4, 11:56 am, Hacid <chadi.alku...@gmail.com> wrote:
>
> > > Hi,
>
> > > I haven't found an existing topic about this, so I ask my question :
>
> > > I develop a package for colleagues. In this package I define a tagged
> > > type. I want to prevent them from doing assignments on this type. But
> > > I want to be able to do these assignments in my body.
>
> > > I understand why I can't define my type limited in the public part and
> > > not limited in the private part. But is there a way to do what I
> > > want ?
>
> > > Something like :
>
> > > package Foo is
>
> > >    type Object is tagged private;
>
> > >    function ":=" (Left : out Object,; Right : in Object) is abstract;
> > > -- I know this looks strange
>
> > > end Foo;
>
> > > Thanks.
>
> > Yes, I think.
> > You could add in an 'indirection step'.
>
> --
> package Whatever is
>
>    type Public_Type is tagged limited private;
>
>    --primitive functions.
>
> private
>
>   -- Base is the type that you will manipulate in the Body.
>   type Base is tagged record
>     -- fields
>      null;
>   end record;
>
>   type Public_Type is new Base with null record;
>
> end Whatever;
> --
> whatever.ads:15:08: completion of limited tagged type must be limited
>
> This way seems to not work ... :o(

After reading your requirements, perhaps this would be the best
way to design what you need/want:

package Whatever is

   Type Public_Type is tagged limited private;

   -- Create constructs an object of Public_Type and may ONLY be used
for
   -- initialization of objects of that type as the type is limited.
   Function Create( Field_1 : In Positive; Field_2 : In Integer )
			Return Public_Type;

   -- Other primitive functions.

private

   Type Public_Type is tagged limited record
   --tagged limited record
      -- Add fields here
      Null;
   end record;

   --Private/hidden functions.

   -- Assign may be used to copy Input to output; this includes
replaceing the
   -- contents of a Public_Type object, which may be done like so:
   --	Assign( Output => Variable, Input => Create(1,128) );
   Procedure Assign( Input : In Public_Type; Output : Out
Public_Type );

end Whatever;



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

* Re: limited /non-limited tagged type
  2011-03-04 22:21     ` Hacid
@ 2011-03-05  1:20       ` Randy Brukardt
  0 siblings, 0 replies; 14+ messages in thread
From: Randy Brukardt @ 2011-03-05  1:20 UTC (permalink / raw)


"Hacid" <chadi.alkurdi@gmail.com> wrote in message 
news:76f09e04-5e4b-42bf-8029-8ac09660655c@r4g2000vbq.googlegroups.com...
> To explain in other words my problem :
> I want to control type assignment but :
> 1) I can't use Ada.Limited_Controlled because I have a ZFP Run Time
> 2) I can't use limited tagged type because I need to perform array
> copies of derivated type
> 3) I can't just say "Do not use assignment" because without checks
> they will do
>
> So I was hoping that Ada have a construct to solve this problem...
> But maybe a rule checker is the best way  :o(

Ada *does* have solutions to this problem, but you've said that you can't 
use them. Fair enough, but you can't expect Ada to have 10 solutions to this 
problem!

(Indeed, Ada often gets critisized for having too many ways to do the same 
thing. But apparently there are never enough ways, either... :-)

                          Randy.





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

* Re: limited /non-limited tagged type
  2011-03-04 22:40       ` Hacid
@ 2011-03-05  1:29         ` Georg Bauhaus
  0 siblings, 0 replies; 14+ messages in thread
From: Georg Bauhaus @ 2011-03-05  1:29 UTC (permalink / raw)


On 3/4/11 11:40 PM, Hacid wrote:

>> private generic
>>      type Element is new Object with private;
>> package Foo_3.Pools is
>>
>> Foo_3.Copy can then effectively be called from within
>> Foo_3.Pools.Copy.
>
>
> I have no compilation error on my file foo_3-pools.adb.
> But this construction make only a partial copy of the derivated
> element.
> And I would want a full one. That was what I tried to explain...but I
> am not very understandable in English :o)

I should wait until you have answered Adam's comments.

Nevertheless, an important distinction might be whether

- Element is your derived type

- Someone else's

In the first case, it is all your Copy operation having access
to all fields of Element.

If Element is all yours, then I don't see how proper nesting
of your Copy procedures might miss a component:

Premises IIUC
===
- The publicly limited objects live in arrays,

- It will be OK to overwrite all object data privately,
per object, as long as the data is written by your own
Copy procedure, and not by someone else's.

Then your private Copy procedures could invoke any parent's
private Copy procedure (assuming all Copy procedures in the
derivation hierarchy can be called by yours).  This will
copy all record components of the parent's view of the object.
When the parent's copy is done, Copy copies the remaining
components.






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

* Re: limited /non-limited tagged type
  2011-03-04 18:56 limited /non-limited tagged type Hacid
                   ` (2 preceding siblings ...)
  2011-03-04 23:34 ` Adam Beneschan
@ 2011-03-05  3:26 ` Adam Beneschan
  2011-03-05 16:48   ` Hacid
  3 siblings, 1 reply; 14+ messages in thread
From: Adam Beneschan @ 2011-03-05  3:26 UTC (permalink / raw)



After looking more closely at the OP's example code, I can think of a
possible case where one *could* argue that a new feature in Ada would
be useful, although I think it's way too obscure to consider adding
anything like this.

package Foo is
    type Object is tagged private;
    procedure Copy (Dest : out Object'Class; Source : in
Object'Class);
private
    type Object is tagged record ... end record;
end Foo;

where the body of Copy says "Dest := Source" and maybe performs some
other functions.

It wouldn't work to make the partial view of Object limited, because
then another package could extend Object by adding a component of
limited type to it, and then Dest := Source, when given objects of
that new type, would copy a limited component, which is a no-no.
However, ***IF*** Ada had a way to say that Object isn't really
limited but still doesn't have assignment visibly defined (i.e.
partially limited??), then things might work.  Since it isn't really
limited, it couldn't be extended with a limited component.  And it
would accomplish the purpose that the OP seems to want: forcing other
packages to use the Copy operation (which wouldn't be overridden, but
would still copy all the components in any type extension) instead of
":=".  I don't know if this really is what's wanted.  I'm sort of
guessing.  Anyway, I think the chance of a feature like this being
added is somewhere between zero and less than zero, and I'm certainly
not going to propose one.

I'd still need more info on just what the OP's needs are.  But if it's
something like I guessed, then perhaps a Copy routine that takes
Object'Class parameters instead of Object is what is wanted.  And
while there's no way to get the compiler to reject other uses of := ,
there's a way to make them blow up at runtime: add a component to
Object whose type is derived from Ada.Finalization.Controlled, and
define an Adjust routine that raises an exception unless a Boolean
flag in the body of Foo is set, and of course Copy would be the only
routine that sets it.

                                  -- Adam



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

* Re: limited /non-limited tagged type
  2011-03-05  3:26 ` Adam Beneschan
@ 2011-03-05 16:48   ` Hacid
  0 siblings, 0 replies; 14+ messages in thread
From: Hacid @ 2011-03-05 16:48 UTC (permalink / raw)


On 5 mar, 04:26, Adam Beneschan <a...@irvine.com> wrote:
> After looking more closely at the OP's example code, I can think of a
> possible case where one *could* argue that a new feature in Ada would
> be useful, although I think it's way too obscure to consider adding
> anything like this.
>
> package Foo is
>     type Object is tagged private;
>     procedure Copy (Dest : out Object'Class; Source : in
> Object'Class);
> private
>     type Object is tagged record ... end record;
> end Foo;
>
> where the body of Copy says "Dest := Source" and maybe performs some
> other functions.
>
> It wouldn't work to make the partial view of Object limited, because
> then another package could extend Object by adding a component of
> limited type to it, and then Dest := Source, when given objects of
> that new type, would copy a limited component, which is a no-no.
> However, ***IF*** Ada had a way to say that Object isn't really
> limited but still doesn't have assignment visibly defined (i.e.
> partially limited??), then things might work.  Since it isn't really
> limited, it couldn't be extended with a limited component.  And it
> would accomplish the purpose that the OP seems to want: forcing other
> packages to use the Copy operation (which wouldn't be overridden, but
> would still copy all the components in any type extension) instead of
> ":=".  I don't know if this really is what's wanted.  I'm sort of
> guessing.  Anyway, I think the chance of a feature like this being
> added is somewhere between zero and less than zero, and I'm certainly
> not going to propose one.
>
> I'd still need more info on just what the OP's needs are.  But if it's
> something like I guessed, then perhaps a Copy routine that takes
> Object'Class parameters instead of Object is what is wanted.  And
> while there's no way to get the compiler to reject other uses of := ,
> there's a way to make them blow up at runtime: add a component to
> Object whose type is derived from Ada.Finalization.Controlled, and
> define an Adjust routine that raises an exception unless a Boolean
> flag in the body of Foo is set, and of course Copy would be the only
> routine that sets it.
>
>                                   -- Adam

You perfectly understand what I want to do.
And I can't explain it better than you.

A good way to do that would be to derivate Object from
Ada.Finalization.Controlled. But as I said I can't due to my ZFP Run
Time use.
I was hoping that there is an other simple way to do the same... But
as Randy said I can't expect Ada to have 10 solutions to a problem.

So I think I will use non limited tagged type with primitive copy
operation and a rule checker to check "no assignement on Object class"
rule.

Thanks to yours answers and your time.



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

end of thread, other threads:[~2011-03-05 16:48 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-04 18:56 limited /non-limited tagged type Hacid
2011-03-04 19:54 ` Edward Fish
2011-03-04 21:18   ` Hacid
2011-03-05  0:17     ` Edward Fish
2011-03-04 20:10 ` Georg Bauhaus
2011-03-04 21:55   ` Hacid
2011-03-04 22:21     ` Hacid
2011-03-05  1:20       ` Randy Brukardt
2011-03-04 22:22     ` Georg Bauhaus
2011-03-04 22:40       ` Hacid
2011-03-05  1:29         ` Georg Bauhaus
2011-03-04 23:34 ` Adam Beneschan
2011-03-05  3:26 ` Adam Beneschan
2011-03-05 16:48   ` Hacid

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