comp.lang.ada
 help / color / mirror / Atom feed
* constructor in abstract tagged types
@ 2019-05-08 18:37 Daniel
  2019-05-08 19:26 ` Dmitry A. Kazakov
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Daniel @ 2019-05-08 18:37 UTC (permalink / raw)



Hello, im trying to know how can i use abstract tagged types and constructors at the same time.

I have this

package FATHERS is
  type Father is abstract tagged record
     Years : Natural;
     field1 : Natural;
--    .....and 15 more fields
  end record;

  function F_build(Years :Natural) return Father is abstract;
  procedure F_forced_to_do_it is abstract;
end FATHERS;

package FATHERS.SONS is
type Son is new father with record
   skate : boolean;
end Son;

function F_Build(Years :Natural) return Son;
procedure F_Forced_to_do_it;
end FATHERS.SONS;

package body FATHERS.SONS is

function F_Build(Years : Natural) return Son is
begin

  ¿?¿?¿?¿?¿?

end F_Build;

end FATHERS.SONS;


---------------------------------
So the question is How can i make the constructor F_Build of the Son?

Option 1:

  return son'(Years => Years,
              field1 => ¿?,
              field2 => ¿?.
              ...
              field15 => ?¿

Problem: put 15 fields by hand for every type of son.. really annoying.

Option 2:

  return Son'(Father with
               Skate =>True);

Problem: i cannot initialize Father or call any kind of constructor of Father becouse compiler don't let me make any kind of function of a abstract tagged type.

Regards,
Daniel.






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

* Re: constructor in abstract tagged types
  2019-05-08 18:37 constructor in abstract tagged types Daniel
@ 2019-05-08 19:26 ` Dmitry A. Kazakov
  2019-05-18 11:31   ` Daniel
  2019-05-08 20:50 ` Jere
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Dmitry A. Kazakov @ 2019-05-08 19:26 UTC (permalink / raw)


On 2019-05-08 20:37, Daniel wrote:

> Hello, im trying to know how can i use abstract tagged types and constructors at the same time.

Ada does not have proper constructors. But there are various software 
patterns to work this around.

> I have this
> 
> package FATHERS is
>    type Father is abstract tagged record
>       Years : Natural;
>       field1 : Natural;
> --    .....and 15 more fields
>    end record;
> 
>    function F_build(Years :Natural) return Father is abstract;
>    procedure F_forced_to_do_it is abstract;

private
    --
    -- Class-wide initialization of Father's fields
    --
    procedure Initialize (Object : in out Father'Class; Years : Natural);

> end FATHERS;
> 
> package FATHERS.SONS is
> type Son is new father with record
>     skate : boolean;
> end Son;
> 
> function F_Build(Years :Natural) return Son;
> procedure F_Forced_to_do_it;
> end FATHERS.SONS;
> 
> package body FATHERS.SONS is
> 
> function F_Build(Years : Natural) return Son is
> begin
      return Result : Son do
         Initialize (Result, Years); -- Parent's "constructor"
         Result.Skate := True;
      end return;
> end F_Build;
> 
> end FATHERS.SONS;

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

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

* Re: constructor in abstract tagged types
  2019-05-08 18:37 constructor in abstract tagged types Daniel
  2019-05-08 19:26 ` Dmitry A. Kazakov
@ 2019-05-08 20:50 ` Jere
  2019-05-10 22:35   ` Randy Brukardt
  2019-05-09 14:40 ` AdaMagica
  2019-05-10 22:40 ` Randy Brukardt
  3 siblings, 1 reply; 10+ messages in thread
From: Jere @ 2019-05-08 20:50 UTC (permalink / raw)


On Wednesday, May 8, 2019 at 2:37:25 PM UTC-4, Daniel wrote:
> Hello, im trying to know how can i use abstract tagged types and constructors at the same time.
> 
> I have this
> 
> <SNIPPED>
> 
> Option 2:
> 
>   return Son'(Father with
>                Skate =>True);
> 
> Problem: i cannot initialize Father or call any kind of constructor of Father becouse compiler don't let me make any kind of function of a abstract tagged type.
> 
> Regards,
> Daniel.

GNAT accepts: 

   function F_Build(Years : Natural) return Son is
   begin
      return (Years => Years, Skate => True, others => <>);
   end F_Build;

I assume since it is abstract you don't have to lead with "Father with"
in the aggregate initialization.  If you need something more complex 
for the other fields you can optionally use extended returns:

   function F_Build(Years : Natural) return Son is
   begin
      return Result : Son := (Years => Years, Skate => True, others => <>) do
         Result.Field1 := -- Something complex;
         ***
      end return;
   end F_Build;

Tested this with GNAT 7.1.1


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

* Re: constructor in abstract tagged types
  2019-05-08 18:37 constructor in abstract tagged types Daniel
  2019-05-08 19:26 ` Dmitry A. Kazakov
  2019-05-08 20:50 ` Jere
@ 2019-05-09 14:40 ` AdaMagica
  2019-05-10  4:46   ` Petter Fryklund
  2019-05-18 11:35   ` Daniel
  2019-05-10 22:40 ` Randy Brukardt
  3 siblings, 2 replies; 10+ messages in thread
From: AdaMagica @ 2019-05-09 14:40 UTC (permalink / raw)


Am Mittwoch, 8. Mai 2019 20:37:25 UTC+2 schrieb Daniel:
Dmitry's solution is the way to do it.

>   procedure F_forced_to_do_it is abstract;

This is not a primitive operation of Fathers.
Declaring it abstract makes it uncallable. So why define it at all.

> package FATHERS.SONS is
> procedure F_Forced_to_do_it;

This is not inherited, so does not override the abstract operation definied in Fathers.
It's also not a primitive operation.

> end FATHERS.SONS;


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

* Re: constructor in abstract tagged types
  2019-05-09 14:40 ` AdaMagica
@ 2019-05-10  4:46   ` Petter Fryklund
  2019-05-18 11:35   ` Daniel
  1 sibling, 0 replies; 10+ messages in thread
From: Petter Fryklund @ 2019-05-10  4:46 UTC (permalink / raw)


Den torsdag 9 maj 2019 kl. 16:40:28 UTC+2 skrev AdaMagica:
> Am Mittwoch, 8. Mai 2019 20:37:25 UTC+2 schrieb Daniel:
> Dmitry's solution is the way to do it.
> 
> >   procedure F_forced_to_do_it is abstract;
> 
> This is not a primitive operation of Fathers.
> Declaring it abstract makes it uncallable. So why define it at all.
> 
> > package FATHERS.SONS is
> > procedure F_Forced_to_do_it;
> 
> This is not inherited, so does not override the abstract operation definied in Fathers.
> It's also not a primitive operation.
> 
> > end FATHERS.SONS;

Adding keyword overriding will generate compiler error:
overriding procedure F_Forced_to_do_it;

which helps.

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

* Re: constructor in abstract tagged types
  2019-05-08 20:50 ` Jere
@ 2019-05-10 22:35   ` Randy Brukardt
  0 siblings, 0 replies; 10+ messages in thread
From: Randy Brukardt @ 2019-05-10 22:35 UTC (permalink / raw)


"Jere" <jhb.chat@gmail.com> wrote in message 
news:58f49c83-eb9d-40d7-9c90-a9523167f63a@googlegroups.com...
...
> GNAT accepts:
>
>   function F_Build(Years : Natural) return Son is
>   begin
>      return (Years => Years, Skate => True, others => <>);
>   end F_Build;
>
> I assume since it is abstract you don't have to lead with "Father with"
> in the aggregate initialization.

It's because the type is fully visible. That's not the usual case for Ada 
abstractions, of course, which is why the extension aggregate is available.

                                  Randy.



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

* Re: constructor in abstract tagged types
  2019-05-08 18:37 constructor in abstract tagged types Daniel
                   ` (2 preceding siblings ...)
  2019-05-09 14:40 ` AdaMagica
@ 2019-05-10 22:40 ` Randy Brukardt
  2019-05-18 11:43   ` Daniel
  3 siblings, 1 reply; 10+ messages in thread
From: Randy Brukardt @ 2019-05-10 22:40 UTC (permalink / raw)


"Daniel" <danielnorberto@gmail.com> wrote in message 
news:0ca05176-a819-4e9a-8c6c-3a0c1f32f964@googlegroups.com...
...
>Option 2:
>
>  return Son'(Father with
 >              Skate =>True);
>
>Problem: i cannot initialize Father or call any kind of constructor of 
>Father
>becouse compiler don't let me make any kind of function of a abstract 
>tagged type.

Correct. But that's what you declared in this case, so I would assume that 
you want to manually initialize all of the components.

If you have proper default values for the components, why not declare the 
Father type that way?? Uninitialized stuff often leads to trouble anyway.

That is:

  type Father is abstract tagged record
     Years : Natural := 0;
     field1 : Natural := 0;
--    .....and 15 more fields
  end record;

If you *don't* want this sort of default value, then it only makes sense to 
initialize all of the components when the object is first created. (Or you 
could define a procedure to do it, as Dmitry showed. But you lose 
completeness checking when you do that.)

                                    Randy.







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

* Re: constructor in abstract tagged types
  2019-05-08 19:26 ` Dmitry A. Kazakov
@ 2019-05-18 11:31   ` Daniel
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel @ 2019-05-18 11:31 UTC (permalink / raw)


El miércoles, 8 de mayo de 2019, 21:26:10 (UTC+2), Dmitry A. Kazakov  escribió:
> On 2019-05-08 20:37, Daniel wrote:
> 
> > Hello, im trying to know how can i use abstract tagged types and constructors at the same time.
> 
> Ada does not have proper constructors. But there are various software 
> patterns to work this around.
> 
> > I have this
> > 
> > package FATHERS is
> >    type Father is abstract tagged record
> >       Years : Natural;
> >       field1 : Natural;
> > --    .....and 15 more fields
> >    end record;
> > 
> >    function F_build(Years :Natural) return Father is abstract;
> >    procedure F_forced_to_do_it is abstract;
> 
> private
>     --
>     -- Class-wide initialization of Father's fields
>     --
>     procedure Initialize (Object : in out Father'Class; Years : Natural);
> 
> > end FATHERS;
> > 
> > package FATHERS.SONS is
> > type Son is new father with record
> >     skate : boolean;
> > end Son;
> > 
> > function F_Build(Years :Natural) return Son;
> > procedure F_Forced_to_do_it;
> > end FATHERS.SONS;
> > 
> > package body FATHERS.SONS is
> > 
> > function F_Build(Years : Natural) return Son is
> > begin
>       return Result : Son do
>          Initialize (Result, Years); -- Parent's "constructor"
>          Result.Skate := True;
>       end return;
> > end F_Build;
> > 
> > end FATHERS.SONS;
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

Thank you Dmitry. It really works for me!


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

* Re: constructor in abstract tagged types
  2019-05-09 14:40 ` AdaMagica
  2019-05-10  4:46   ` Petter Fryklund
@ 2019-05-18 11:35   ` Daniel
  1 sibling, 0 replies; 10+ messages in thread
From: Daniel @ 2019-05-18 11:35 UTC (permalink / raw)


El jueves, 9 de mayo de 2019, 16:40:28 (UTC+2), AdaMagica  escribió:
> Am Mittwoch, 8. Mai 2019 20:37:25 UTC+2 schrieb Daniel:
> Dmitry's solution is the way to do it.
> 
> >   procedure F_forced_to_do_it is abstract;
> 
> This is not a primitive operation of Fathers.
> Declaring it abstract makes it uncallable. So why define it at all.
> 
> > package FATHERS.SONS is
> > procedure F_Forced_to_do_it;
> 
> This is not inherited, so does not override the abstract operation definied in Fathers.
> It's also not a primitive operation.
> 
> > end FATHERS.SONS;

I declare it as an obligated "interface". I want that any children that extend father has to implement it.

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

* Re: constructor in abstract tagged types
  2019-05-10 22:40 ` Randy Brukardt
@ 2019-05-18 11:43   ` Daniel
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel @ 2019-05-18 11:43 UTC (permalink / raw)


El sábado, 11 de mayo de 2019, 0:40:48 (UTC+2), Randy Brukardt  escribió:
> "Daniel" wrote in message 
> ...
> ...
> >Option 2:
> >
> >  return Son'(Father with
>  >              Skate =>True);
> >
> >Problem: i cannot initialize Father or call any kind of constructor of 
> >Father
> >becouse compiler don't let me make any kind of function of a abstract 
> >tagged type.
> 
> Correct. But that's what you declared in this case, so I would assume that 
> you want to manually initialize all of the components.
> 
> If you have proper default values for the components, why not declare the 
> Father type that way?? Uninitialized stuff often leads to trouble anyway.
> 
> That is:
> 
>   type Father is abstract tagged record
>      Years : Natural := 0;
>      field1 : Natural := 0;
> --    .....and 15 more fields
>   end record;
> 
> If you *don't* want this sort of default value, then it only makes sense to 
> initialize all of the components when the object is first created. (Or you 
> could define a procedure to do it, as Dmitry showed. But you lose 
> completeness checking when you do that.)
> 
>                                     Randy.

Thank you for your answer.
Yes. In the real component i will want to initialize to some known value for some attributes, but there are other that i need to change from the son constructor.


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

end of thread, other threads:[~2019-05-18 11:43 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-08 18:37 constructor in abstract tagged types Daniel
2019-05-08 19:26 ` Dmitry A. Kazakov
2019-05-18 11:31   ` Daniel
2019-05-08 20:50 ` Jere
2019-05-10 22:35   ` Randy Brukardt
2019-05-09 14:40 ` AdaMagica
2019-05-10  4:46   ` Petter Fryklund
2019-05-18 11:35   ` Daniel
2019-05-10 22:40 ` Randy Brukardt
2019-05-18 11:43   ` Daniel

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