comp.lang.ada
 help / color / mirror / Atom feed
* limited agregate and limited components default initialization
@ 2018-03-31 23:36 Jean-Claude Rostaing
  2018-04-01  0:52 ` Jere
                   ` (3 more replies)
  0 siblings, 4 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-03-31 23:36 UTC (permalink / raw)


Why does a component declaration like that:
type Item_Accessor (Item: not null access Item_type) is limited record
      Ref: Item_access := SET(Item_Record'(Item => ITEM.all, others => <>));
   end record;
unconstrained subtype in component declaration
? ITEM is limited but IS constrained by the default initialisation
It forced me to add the function DEFAULT_INITIALIZATION as a parameter, which I would prefer to not to. But since the result is the same, I'll drop it.
Item (and the article it is in) is never meant to be left uninitialized.

Also, how to get rid of the problem with
function Set (Value: in Item_type) return Smart_Pointers is
     (Smart_Pointers'(Controlled with Node => new Accessor_type'(Data => new Item_type'(Value), Count => 1)));
which gives :Initialization not allowed for limited types.
So an aggregate like this is not counted as a "limited agregate" ??


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

* Re: limited agregate and limited components default initialization
  2018-03-31 23:36 limited agregate and limited components default initialization Jean-Claude Rostaing
@ 2018-04-01  0:52 ` Jere
  2018-04-01  1:12   ` Jere
  2018-04-01  1:16   ` Jean-Claude Rostaing
  2018-04-01 13:33 ` Dmitry A. Kazakov
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 43+ messages in thread
From: Jere @ 2018-04-01  0:52 UTC (permalink / raw)


On Saturday, March 31, 2018 at 7:36:59 PM UTC-4, Jean-Claude Rostaing wrote:
> Why does a component declaration like that:
> type Item_Accessor (Item: not null access Item_type) is limited record
>       Ref: Item_access := SET(Item_Record'(Item => ITEM.all, others => <>));
>    end record;
> unconstrained subtype in component declaration
> ? ITEM is limited but IS constrained by the default initialisation
> It forced me to add the function DEFAULT_INITIALIZATION as a parameter, which I would prefer to not to. But since the result is the same, I'll drop it.
> Item (and the article it is in) is never meant to be left uninitialized.
> 
> Also, how to get rid of the problem with
> function Set (Value: in Item_type) return Smart_Pointers is
>      (Smart_Pointers'(Controlled with Node => new Accessor_type'(Data => new Item_type'(Value), Count => 1)));
> which gives :Initialization not allowed for limited types.
> So an aggregate like this is not counted as a "limited agregate" ??

I may be misunderstanding you, but if Item is a limited type with a default
discriminant, it is "unconstrained" since the ada compiler cannot know
at compile time what the actual size will be.

See:
https://gcc.gnu.org/onlinedocs/gnat_rm/The-Size-of-Discriminated-Records-with-Default-Discriminants.html


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

* Re: limited agregate and limited components default initialization
  2018-04-01  0:52 ` Jere
@ 2018-04-01  1:12   ` Jere
  2018-04-01  1:16   ` Jean-Claude Rostaing
  1 sibling, 0 replies; 43+ messages in thread
From: Jere @ 2018-04-01  1:12 UTC (permalink / raw)


On Saturday, March 31, 2018 at 8:52:39 PM UTC-4, Jere wrote:
> On Saturday, March 31, 2018 at 7:36:59 PM UTC-4, Jean-Claude Rostaing wrote:
> > Why does a component declaration like that:
> > type Item_Accessor (Item: not null access Item_type) is limited record
> >       Ref: Item_access := SET(Item_Record'(Item => ITEM.all, others => <>));
> >    end record;
> > unconstrained subtype in component declaration
> > ? ITEM is limited but IS constrained by the default initialisation
> > It forced me to add the function DEFAULT_INITIALIZATION as a parameter, which I would prefer to not to. But since the result is the same, I'll drop it.
> > Item (and the article it is in) is never meant to be left uninitialized.
> > 
> > Also, how to get rid of the problem with
> > function Set (Value: in Item_type) return Smart_Pointers is
> >      (Smart_Pointers'(Controlled with Node => new Accessor_type'(Data => new Item_type'(Value), Count => 1)));
> > which gives :Initialization not allowed for limited types.
> > So an aggregate like this is not counted as a "limited agregate" ??
> 
> I may be misunderstanding you, but if Item is a limited type with a default
> discriminant, it is "unconstrained" since the ada compiler cannot know
> at compile time what the actual size will be.
> 
> See:
> https://gcc.gnu.org/onlinedocs/gnat_rm/The-Size-of-Discriminated-Records-with-Default-Discriminants.html

Actually, the limited might make it ok, but I seem to remember it still being 
considered unconstrained from a language point of view.  Perhaps a language 
lawyer type can make a better comment.


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

* Re: limited agregate and limited components default initialization
  2018-04-01  0:52 ` Jere
  2018-04-01  1:12   ` Jere
@ 2018-04-01  1:16   ` Jean-Claude Rostaing
  2018-04-01  1:34     ` Jere
  1 sibling, 1 reply; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-01  1:16 UTC (permalink / raw)


Interesting.
Let's say I get that - not quite done in reality, ITEM_TYPE's formal type
is "(<>) is limited private", so why giving a default expression -not discriminant- isn't enough to constrain the component's value ? 

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

* Re: limited agregate and limited components default initialization
  2018-04-01  1:16   ` Jean-Claude Rostaing
@ 2018-04-01  1:34     ` Jere
  2018-04-01  2:07       ` Jean-Claude Rostaing
  0 siblings, 1 reply; 43+ messages in thread
From: Jere @ 2018-04-01  1:34 UTC (permalink / raw)


On Saturday, March 31, 2018 at 9:16:49 PM UTC-4, Jean-Claude Rostaing wrote:
> Interesting.
> Let's say I get that - not quite done in reality, ITEM_TYPE's formal type
> is "(<>) is limited private", so why giving a default expression -not discriminant- isn't enough to constrain the component's value ?

As I said in my second response, the limited might make it ok (I don't know
for sure now that I think about it), but when I looked at the RM, the section
on discriminants didn't mention limited types.

I thought you meant discriminant.  If you meant expression, I'm not sure.
My apologies!

Can you give a slightly more complete example?  The one earlier was fairly
incomplete.  I couldn't tell what Item_Record type looked like for example.

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

* Re: limited agregate and limited components default initialization
  2018-04-01  1:34     ` Jere
@ 2018-04-01  2:07       ` Jean-Claude Rostaing
  2018-04-01  2:40         ` Jere
                           ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-01  2:07 UTC (permalink / raw)


--
-- Item_type and ITEM_RECORD are NOT meant to be declared uninitialized, ever.
-- So how do I tell this to GNAT so that Item: aliased ITEM_TYPE as a component is allowed ?
-- Implementing List_type with common access types and "type Bla, type Blabla is access Bla, complete declaration" would have been easy, but the private type Smart_Pointers made a hell of it.

with Pointers;

generic
   type Item_Type(<>) is limited private;
package Lists is
   type List_Type is limited private;
   type Item_Accessor (Item: not null access Item_type) is limited private with Implicit_Dereference => Item;
      function Get(Position: in List_Iterator) return Item_Accessor;
private
   type ITEM_ACCESS;
   type Item_Record is limited
      record
         Item: aliased Item_type;
         Next : Item_Access;
         Pred : Item_Access;
      end record;
   package Record_Pointers is new Pointers (Item_type => Item_Record);
   type Item_Access is new Record_Pointers.Smart_Pointers;

   type Item_Accessor (Item: not null access Item_type) is limited record
      REF: ITEM_ACCESS := SET(ITEM_RECORD'(ITEM.all, others => <>));
   end record;

   type List_Type is limited record
      First: Item_Access;
      Last : Item_Access;
      Count : Natural := 1;
   end record;
end Lists;

And what I was pointing your attention at was:
lists.ads:39:49: initialization not allowed for limited types
for: REF: ITEM_ACCESS := SET(ITEM_RECORD'(ITEM.all, others => <>));


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

* Re: limited agregate and limited components default initialization
  2018-04-01  2:07       ` Jean-Claude Rostaing
@ 2018-04-01  2:40         ` Jere
  2018-04-01  2:54           ` Jere
  2018-04-01  3:14         ` Jere
  2018-04-01  9:32         ` Jacob Sparre Andersen
  2 siblings, 1 reply; 43+ messages in thread
From: Jere @ 2018-04-01  2:40 UTC (permalink / raw)


On Saturday, March 31, 2018 at 10:07:20 PM UTC-4, Jean-Claude Rostaing wrote:
> --
> -- Item_type and ITEM_RECORD are NOT meant to be declared uninitialized, ever.
> -- So how do I tell this to GNAT so that Item: aliased ITEM_TYPE as a component is allowed ?
> -- Implementing List_type with common access types and "type Bla, type Blabla is access Bla, complete declaration" would have been easy, but the private type Smart_Pointers made a hell of it.
> 
> with Pointers;
> 
> generic
>    type Item_Type(<>) is limited private;
> package Lists is
>    type List_Type is limited private;
>    type Item_Accessor (Item: not null access Item_type) is limited private with Implicit_Dereference => Item;
>       function Get(Position: in List_Iterator) return Item_Accessor;
> private
>    type ITEM_ACCESS;
>    type Item_Record is limited
>       record
>          Item: aliased Item_type;
>          Next : Item_Access;
>          Pred : Item_Access;
>       end record;
>    package Record_Pointers is new Pointers (Item_type => Item_Record);
>    type Item_Access is new Record_Pointers.Smart_Pointers;
> 
>    type Item_Accessor (Item: not null access Item_type) is limited record
>       REF: ITEM_ACCESS := SET(ITEM_RECORD'(ITEM.all, others => <>));
>    end record;
> 
>    type List_Type is limited record
>       First: Item_Access;
>       Last : Item_Access;
>       Count : Natural := 1;
>    end record;
> end Lists;
> 
> And what I was pointing your attention at was:
> lists.ads:39:49: initialization not allowed for limited types
> for: REF: ITEM_ACCESS := SET(ITEM_RECORD'(ITEM.all, others => <>));

Ok, your problems:
1.  For  your Item_Record type, the parameter Item, cannot be of type
    Item_Type as it is unconstrained.  That is what gives you the first
    error
2.  Item'(Item.all, others => <>) ==>  The problem here is "Item.all".
    You are essentially trying to initialize a limited component with
    a limited variable and copying a limited variable is not allowed.

you need a function that builds a limited type of type Item_Type and use
that in place of Set.  It has to be aggregate initialization.  What you
are trying to do is copy a limited variable to initialize another.
Essentially your Lists package needs to be modified:

generic
    type Item_Type is limited private;  --removed unconstrained
    with function Make_Item return Item_Type;
package Lists is

then your set call is:

REF: ITEM_ACCESS := SET(Make_Item);


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

* Re: limited agregate and limited components default initialization
  2018-04-01  2:40         ` Jere
@ 2018-04-01  2:54           ` Jere
  0 siblings, 0 replies; 43+ messages in thread
From: Jere @ 2018-04-01  2:54 UTC (permalink / raw)


On Saturday, March 31, 2018 at 10:40:22 PM UTC-4, Jere wrote:
> On Saturday, March 31, 2018 at 10:07:20 PM UTC-4, Jean-Claude Rostaing wrote:
> > --
> > -- Item_type and ITEM_RECORD are NOT meant to be declared uninitialized, ever.
> > -- So how do I tell this to GNAT so that Item: aliased ITEM_TYPE as a component is allowed ?
> > -- Implementing List_type with common access types and "type Bla, type Blabla is access Bla, complete declaration" would have been easy, but the private type Smart_Pointers made a hell of it.
> > 
> > with Pointers;
> > 
> > generic
> >    type Item_Type(<>) is limited private;
> > package Lists is
> >    type List_Type is limited private;
> >    type Item_Accessor (Item: not null access Item_type) is limited private with Implicit_Dereference => Item;
> >       function Get(Position: in List_Iterator) return Item_Accessor;
> > private
> >    type ITEM_ACCESS;
> >    type Item_Record is limited
> >       record
> >          Item: aliased Item_type;
> >          Next : Item_Access;
> >          Pred : Item_Access;
> >       end record;
> >    package Record_Pointers is new Pointers (Item_type => Item_Record);
> >    type Item_Access is new Record_Pointers.Smart_Pointers;
> > 
> >    type Item_Accessor (Item: not null access Item_type) is limited record
> >       REF: ITEM_ACCESS := SET(ITEM_RECORD'(ITEM.all, others => <>));
> >    end record;
> > 
> >    type List_Type is limited record
> >       First: Item_Access;
> >       Last : Item_Access;
> >       Count : Natural := 1;
> >    end record;
> > end Lists;
> > 
> > And what I was pointing your attention at was:
> > lists.ads:39:49: initialization not allowed for limited types
> > for: REF: ITEM_ACCESS := SET(ITEM_RECORD'(ITEM.all, others => <>));
> 
> Ok, your problems:
> 1.  For  your Item_Record type, the parameter Item, cannot be of type
>     Item_Type as it is unconstrained.  That is what gives you the first
>     error
To clarify because I typed that horribly:  Item_Type cannot be an 
unconstrained type if you wish to make it a component of a record.
It needs a constraint.  That's why you have to remove the (<>)
in your generic formal for Item_Type.

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

* Re: limited agregate and limited components default initialization
  2018-04-01  2:07       ` Jean-Claude Rostaing
  2018-04-01  2:40         ` Jere
@ 2018-04-01  3:14         ` Jere
  2018-04-01  3:31           ` Jere
  2018-04-01  9:32         ` Jacob Sparre Andersen
  2 siblings, 1 reply; 43+ messages in thread
From: Jere @ 2018-04-01  3:14 UTC (permalink / raw)


On Saturday, March 31, 2018 at 10:07:20 PM UTC-4, Jean-Claude Rostaing wrote:
>    type ITEM_ACCESS;
>    type Item_Record is limited
>       record
>          Item: aliased Item_type;
>          Next : Item_Access;
>          Pred : Item_Access;
>       end record;
>    package Record_Pointers is new Pointers (Item_type => Item_Record);
>    type Item_Access is new Record_Pointers.Smart_Pointers;

Side note:  I couldn't get this to compile because Next and Pred
are incomplete types (so they too cannot be used a variable types.

The proper way to do it would be:
       type Item_Record;
       package Record_Pointers is new Pointers (Item_type => Item_Record);
       type Item_Access is new Record_Pointers.Smart_Pointers; 
    
       type Item_Record is limited
          record
             Item : aliased Item_type;
             Next : Item_Access;
             Pred : Item_Access;
          end record;

but your Pointers package will need an incomplete formal type for it to
work:

    generic
        type Item_Type(<>);
    package Pointers is
        -- stuff
    end Pointers;

and that might cause you other problems, but if you want to use
your smart pointers in a self referential type, you'll need your
smart pointer generic to use incomplete types.


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

* Re: limited agregate and limited components default initialization
  2018-04-01  3:14         ` Jere
@ 2018-04-01  3:31           ` Jere
  0 siblings, 0 replies; 43+ messages in thread
From: Jere @ 2018-04-01  3:31 UTC (permalink / raw)


On Saturday, March 31, 2018 at 11:14:49 PM UTC-4, Jere wrote:
> On Saturday, March 31, 2018 at 10:07:20 PM UTC-4, Jean-Claude Rostaing wrote:
> >    type ITEM_ACCESS;
> >    type Item_Record is limited
> >       record
> >          Item: aliased Item_type;
> >          Next : Item_Access;
> >          Pred : Item_Access;
> >       end record;
> >    package Record_Pointers is new Pointers (Item_type => Item_Record);
> >    type Item_Access is new Record_Pointers.Smart_Pointers;
> 
> Side note:  I couldn't get this to compile because Next and Pred
> are incomplete types (so they too cannot be used a variable types.
> 
> The proper way to do it would be:
>        type Item_Record;
>        package Record_Pointers is new Pointers (Item_type => Item_Record);
>        type Item_Access is new Record_Pointers.Smart_Pointers; 
>     
>        type Item_Record is limited
>           record
>              Item : aliased Item_type;
>              Next : Item_Access;
>              Pred : Item_Access;
>           end record;
> 
> but your Pointers package will need an incomplete formal type for it to
> work:
> 
>     generic
>         type Item_Type(<>);
>     package Pointers is
>         -- stuff
>     end Pointers;
> 
> and that might cause you other problems, but if you want to use
> your smart pointers in a self referential type, you'll need your
> smart pointer generic to use incomplete types.

Since you didn't supply a minimally compilable example, I made a 
quick one stubbing in the things you didn't specify.  Hopefully
this will help give some ideas on what I mean:

procedure jdoodle is

    generic
        type Item_Type(<>);
    package Pointers is
        type Smart_Pointers is limited null record;
    end Pointers;

    generic
       type Item_Type is limited private;
       with function Make_Item return Item_Type;
    package Lists is
       type List_Type is limited private;
       type Item_Accessor (Item: not null access Item_type) is limited private with Implicit_Dereference => Item; 
       
       -- added stub
       type List_Iterator is limited record
            Ref : access Item_Type;
       end record;
       
       function Get(Position: in List_Iterator) return Item_Accessor;
    private
        type Item_Record;
        package Record_Pointers is new Pointers (Item_type => Item_Record);
        type Item_Access is new Record_Pointers.Smart_Pointers; 
    
       type Item_Record is limited
          record
             Item : aliased Item_type;
             Next : Item_Access;
             Pred : Item_Access;
          end record;
          
        -- Added stub
        function Set(value : Item_Record) return Item_Access is (others => <>);
       
        type Item_Accessor (Item: not null access Item_type) is limited record
            REF: ITEM_ACCESS := Set(Item_Record'(Make_Item, others => <>));
        end record;
        
        function Get(Position: in List_Iterator) return Item_Accessor is (Item => Position.Ref, others => <>);
       
       type List_Type is limited record
          First: Item_Access;
          Last : Item_Access;
          Count : Natural := 1;
        end record; 
    end lists;
    
    
    -----------------------------------------------------------
    -- Testing package instantiation
    -----------------------------------------------------------
    type Test is record
        value : Integer := 0;
    end record;
    function Make_Test return Test is (value => 10);
    
    package Test_Lists is new Lists(Item_Type => Test, Make_Item => Make_Test);
begin
    null;
end jdoodle;


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

* Re: limited agregate and limited components default initialization
  2018-04-01  2:07       ` Jean-Claude Rostaing
  2018-04-01  2:40         ` Jere
  2018-04-01  3:14         ` Jere
@ 2018-04-01  9:32         ` Jacob Sparre Andersen
  2018-04-01 12:58           ` Jean-Claude Rostaing
  2 siblings, 1 reply; 43+ messages in thread
From: Jacob Sparre Andersen @ 2018-04-01  9:32 UTC (permalink / raw)


Jean-Claude Rostaing wrote:

> -- Item_type and ITEM_RECORD are NOT meant to be declared
> uninitialized, ever.

That one is easy:

   type Item_Type (<>) is private;
   type Item_Record (<>) is private;

Then you can only declare variables of the type with explicit
initialization.

Greetings,

Jacob
-- 
Rent-a-Minion Inc. Because good help is so hard to find.


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

* Re: limited agregate and limited components default initialization
  2018-04-01  9:32         ` Jacob Sparre Andersen
@ 2018-04-01 12:58           ` Jean-Claude Rostaing
  0 siblings, 0 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-01 12:58 UTC (permalink / raw)


    generic 
        type Item_Type(<>); 
    package Pointers is 
        type Smart_Pointers is limited null record; 
    end Pointers; 

It would be logical, but it is impractical, because of
(Value: in Item_type) return Smart_Pointers is
     (Smart_Pointers'(Controlled with Node => new Accessor_type'(Data => new Item_type'(Value), Count => 1)));
« initialization not allowed for a limited type » becomes :
pointers2.adb:18:18: invalid use of formal incomplete type
pointers2.adb:19:87: premature usage of incomplete type "Item_type" defined at pointers2.ads:4

To Jacob : 
   type Item_Type (<>) is private; 
   type Item_Record (<>) is private;
Sure ! It’s already done for Item_type (see the generic parameter ;-) ) and Item_Record is declared in the private part, so « unknown discriminant is not allowed ». Such a shame, it would be useful to tell the compiler that you’re not declare initialized stuff even in the body, even though you know the discriminants.


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

* Re: limited agregate and limited components default initialization
  2018-03-31 23:36 limited agregate and limited components default initialization Jean-Claude Rostaing
  2018-04-01  0:52 ` Jere
@ 2018-04-01 13:33 ` Dmitry A. Kazakov
  2018-04-01 15:46   ` Jean-Claude Rostaing
  2018-04-01 22:52 ` Jean-Claude Rostaing
  2018-04-03 18:18 ` Jean-Claude Rostaing
  3 siblings, 1 reply; 43+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-01 13:33 UTC (permalink / raw)


On 2018-04-01 01:36, Jean-Claude Rostaing wrote:
> Why does a component declaration like that:
> type Item_Accessor (Item: not null access Item_type) is limited record
>        Ref: Item_access := SET(Item_Record'(Item => ITEM.all, others => <>));
>     end record;
> unconstrained subtype in component declaration
> ? ITEM is limited but IS constrained by the default initialisation

Smart pointer is limited? It does not make sense to me.

P.S. Unless you are trying to work around some very specific language 
deficiency, e.g. lack of in-place operations for container types.

P.P.S. Limited aggregates do not work, no matter how you turn it. I am 
afraid you are wasting your time. Even if you get this working somehow 
this time, they will hit you somewhere later.

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


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

* Re: limited agregate and limited components default initialization
  2018-04-01 13:33 ` Dmitry A. Kazakov
@ 2018-04-01 15:46   ` Jean-Claude Rostaing
  2018-04-01 15:53     ` Jean-Claude Rostaing
  2018-04-02  3:42     ` Randy Brukardt
  0 siblings, 2 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-01 15:46 UTC (permalink / raw)


the smart pointer is NOT limited, but ITEM_TYPE is. Simply because I want to accept as many type as possible.

generic
   type Item_type(<>) is limited private;
package Pointers is
   type Accessor_type(Data: not null access Item_type) is limited private with Implicit_Dereference => Data;
   type Smart_Pointers(<>) is private;
   NULL_ACCESS: Constant Smart_Pointers;

I could ask a constructor as a parameter, but it would be stupid since clients whou would want to instanciate with a limited type, won'obviously wouldn't be able to provide a constructor.

I'm waiting for a solution... Randy the savior ?


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

* Re: limited agregate and limited components default initialization
  2018-04-01 15:46   ` Jean-Claude Rostaing
@ 2018-04-01 15:53     ` Jean-Claude Rostaing
  2018-04-01 15:54       ` Jean-Claude Rostaing
  2018-04-01 21:31       ` Dmitry A. Kazakov
  2018-04-02  3:42     ` Randy Brukardt
  1 sibling, 2 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-01 15:53 UTC (permalink / raw)


My real problem is that the implicit dereference aspect NEEDS an access discriminant, and can't take a named access type.
... or anonymous access type shall be allowed to be GENERAL, which I surely don't advocate for.

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

* Re: limited agregate and limited components default initialization
  2018-04-01 15:53     ` Jean-Claude Rostaing
@ 2018-04-01 15:54       ` Jean-Claude Rostaing
  2018-04-01 21:31       ` Dmitry A. Kazakov
  1 sibling, 0 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-01 15:54 UTC (permalink / raw)


My real problem is that the implicit dereference aspect NEEDS an access discriminant, and can't take a named access type.
... or anonymous access type shall be allowed to be GENERAL, which I surely don't advocate for.
If either of those two things were possible, I wouldn't have to use an allocator in my exemple.


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

* Re: limited agregate and limited components default initialization
  2018-04-01 15:53     ` Jean-Claude Rostaing
  2018-04-01 15:54       ` Jean-Claude Rostaing
@ 2018-04-01 21:31       ` Dmitry A. Kazakov
  2018-04-02  3:44         ` Randy Brukardt
  1 sibling, 1 reply; 43+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-01 21:31 UTC (permalink / raw)


On 2018-04-01 17:53, Jean-Claude Rostaing wrote:
> My real problem is that the implicit dereference aspect NEEDS an access discriminant, and can't take a named access type.
> ... or anonymous access type shall be allowed to be GENERAL, which I surely don't advocate for.

Well, implicit dereference will never work with smart pointers because 
it uses access discriminant (instead of a component). There is nothing 
you could do about it. It simply was not designed for user-defined 
access types.

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

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

* Re: limited agregate and limited components default initialization
  2018-03-31 23:36 limited agregate and limited components default initialization Jean-Claude Rostaing
  2018-04-01  0:52 ` Jere
  2018-04-01 13:33 ` Dmitry A. Kazakov
@ 2018-04-01 22:52 ` Jean-Claude Rostaing
  2018-04-01 23:36   ` Jean-Claude Rostaing
  2018-04-03 18:18 ` Jean-Claude Rostaing
  3 siblings, 1 reply; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-01 22:52 UTC (permalink / raw)


... I don't count the number of such negative posts or yours... you should worry, you might get ulcera or cancer with such a mindset.

Kidding aside, ok, access discriminant. No problem. I suppose they did so as they wanted the accessed object to be bound for its life time, with the accessor type, I understand the reason.
I'll dig into the book to see their own implementation, which did accepted non limited types (whereas I had to make it simply unconstrained private). The buggy part in mine wasn't the accesor type, so I'm positive I can tweak their implementation to add implicit dereference. I'll come back after.


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

* Re: limited agregate and limited components default initialization
  2018-04-01 22:52 ` Jean-Claude Rostaing
@ 2018-04-01 23:36   ` Jean-Claude Rostaing
  2018-04-01 23:39     ` Jean-Claude Rostaing
  2018-04-02 22:39     ` Robert I. Eachus
  0 siblings, 2 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-01 23:36 UTC (permalink / raw)


Ok, now I know why what I wanted to do was impossible. To store an object into an accessor or whatever, or to create it with allocator, with only a given "value" of this limited type, you need to COPY this value, whatever you do. Which goes against the very idea of limited type.
I feel more intelligent thanks to that...


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

* Re: limited agregate and limited components default initialization
  2018-04-01 23:36   ` Jean-Claude Rostaing
@ 2018-04-01 23:39     ` Jean-Claude Rostaing
  2018-04-02 18:19       ` Jere
  2018-04-02 22:39     ` Robert I. Eachus
  1 sibling, 1 reply; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-01 23:39 UTC (permalink / raw)


Ok, now I know why what I wanted to do was impossible. To store an object into an accessor or whatever, or to create it with allocator, with only a given "value" of this limited type, you need to COPY this value, whatever you do. Which goes against the very idea of limited type.
I feel more intelligent thanks to that...
And I know why though ITEM_TYPE is indefinite limited, you can only translate from its POINTER to a smart pointer, never directly from a value of that limited type.


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

* Re: limited agregate and limited components default initialization
  2018-04-01 15:46   ` Jean-Claude Rostaing
  2018-04-01 15:53     ` Jean-Claude Rostaing
@ 2018-04-02  3:42     ` Randy Brukardt
  1 sibling, 0 replies; 43+ messages in thread
From: Randy Brukardt @ 2018-04-02  3:42 UTC (permalink / raw)



"Jean-Claude Rostaing" <00120260a@gmail.com> wrote in message 
news:29943b13-00d1-443a-82f2-f55272770109@googlegroups.com...
> the smart pointer is NOT limited, but ITEM_TYPE is. Simply because I want 
> to accept as many type as possible.
>
> generic
>   type Item_type(<>) is limited private;
> package Pointers is
>   type Accessor_type(Data: not null access Item_type) is limited private 
> with Implicit_Dereference => Data;
>   type Smart_Pointers(<>) is private;
>   NULL_ACCESS: Constant Smart_Pointers;
>
> I could ask a constructor as a parameter, but it would be stupid since 
> clients whou would want to instanciate with a limited type, won'obviously 
> wouldn't be able to provide a constructor.
>
> I'm waiting for a solution... Randy the savior ?

A limited type can have a constructor function -- it just has to really 
construct the type, not copy it as you are doing in your examples. It won't 
work to solve *every* problem, but it will solve most. (Dmitry is a little 
too pessimistic in his assessment.)

               Randy.



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

* Re: limited agregate and limited components default initialization
  2018-04-01 21:31       ` Dmitry A. Kazakov
@ 2018-04-02  3:44         ` Randy Brukardt
  2018-04-02 11:25           ` Jean-Claude Rostaing
  2018-04-05 10:27           ` AdaMagica
  0 siblings, 2 replies; 43+ messages in thread
From: Randy Brukardt @ 2018-04-02  3:44 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:p9rj2t$td5$1@gioia.aioe.org...
> On 2018-04-01 17:53, Jean-Claude Rostaing wrote:
>> My real problem is that the implicit dereference aspect NEEDS an access 
>> discriminant, and can't take a named access type.
>> ... or anonymous access type shall be allowed to be GENERAL, which I 
>> surely don't advocate for.
>
> Well, implicit dereference will never work with smart pointers because it 
> uses access discriminant (instead of a component). There is nothing you 
> could do about it. It simply was not designed for user-defined access 
> types.

It won't always work directly. The implicit dereference usually needs to be 
a separate (helper) object from the smart pointer. I believe Christophe 
Grein has a working implementation (but I forget the link).

                   Randy.



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

* Re: limited agregate and limited components default initialization
  2018-04-02  3:44         ` Randy Brukardt
@ 2018-04-02 11:25           ` Jean-Claude Rostaing
  2018-04-02 12:11             ` Dmitry A. Kazakov
                               ` (2 more replies)
  2018-04-05 10:27           ` AdaMagica
  1 sibling, 3 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-02 11:25 UTC (permalink / raw)


It works, so much for "impossible" dmitry.

I probably read before the implementation you mentioned, I don't remember exactly. I saw something strange writing this. Shouldn't the expression function 
function GET (Pointer : Pointer_Type) return Accessor_Type is
     (if Pointer.Pointer = null or else POINTER.Pointer.Value = null then raise EXC_NULL_POINTER_ACCESS
      else ACCESSOR_TYPE'(Data_Link => Pointer.Pointer.Value));
be strictly equivalent to 
function GET (Pointer : Pointer_Type) return Accessor_Type is
   begin
      if Pointer.Pointer = null or else POINTER.Pointer.Value = null then raise EXC_NULL_POINTER_ACCESS;
      else
         return ACCESSOR_TYPE'(Data_Link => Pointer.Pointer.Value);
      end if;
   end GET;
? Yet no, the second is fine, the second raises at run time
raised CONSTRAINT_ERROR : pointers.adb:20 discriminant check failed

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

* Re: limited agregate and limited components default initialization
  2018-04-02 11:25           ` Jean-Claude Rostaing
@ 2018-04-02 12:11             ` Dmitry A. Kazakov
  2018-04-02 12:15             ` Jean-Claude Rostaing
  2018-04-02 21:37             ` Randy Brukardt
  2 siblings, 0 replies; 43+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-02 12:11 UTC (permalink / raw)


On 2018-04-02 13:25, Jean-Claude Rostaing wrote:
> It works, so much for "impossible" dmitry.
> 
> I probably read before the implementation you mentioned, I don't remember exactly. I saw something strange writing this. Shouldn't the expression function
> function GET (Pointer : Pointer_Type) return Accessor_Type is
>       (if Pointer.Pointer = null or else POINTER.Pointer.Value = null then raise EXC_NULL_POINTER_ACCESS
>        else ACCESSOR_TYPE'(Data_Link => Pointer.Pointer.Value));
> be strictly equivalent to
> function GET (Pointer : Pointer_Type) return Accessor_Type is
>     begin
>        if Pointer.Pointer = null or else POINTER.Pointer.Value = null then raise EXC_NULL_POINTER_ACCESS;
>        else
>           return ACCESSOR_TYPE'(Data_Link => Pointer.Pointer.Value);
>        end if;
>     end GET;
> ? Yet no, the second is fine, the second raises at run time
> raised CONSTRAINT_ERROR : pointers.adb:20 discriminant check failed

You still cannot dereference you smart pointer without an explicit call 
to Get. You could just make Get returning an anonymous access to the 
target and be done with that.

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


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

* Re: limited agregate and limited components default initialization
  2018-04-02 11:25           ` Jean-Claude Rostaing
  2018-04-02 12:11             ` Dmitry A. Kazakov
@ 2018-04-02 12:15             ` Jean-Claude Rostaing
  2018-04-02 21:37             ` Randy Brukardt
  2 siblings, 0 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-02 12:15 UTC (permalink / raw)


I saw something else too, and I suspect it has to do with the changing rules for anonymous access types conversion form 95 to 2012:
This:         Token := Pointer(Value => new End_Of_Expression);
is my book, it doesn't work, it says:
expressions.adb:40:32: expected type "TOKEN_ACCESS" defined at expressions.ads:12
expressions.adb:40:32: found type access to "End_Of_Expression" defined at line 40
TOKEN_ACCESS is a mere (public) named access type. I am positive I changed nothing to the Pointer function, except its name, to "Set".
And converting to TOKEN_ACCESS leads to this:
argument of conversion cannot be an allocator
expressions.adb:40:32: use qualified expression instead
expressions.adb:40:32: target type must be general access type
expressions.adb:40:32: add "all" to type "TOKEN_ACCESS" defined at 

I sure DON'T want to make it a general access type, I don't see why I should !

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

* Re: limited agregate and limited components default initialization
  2018-04-01 23:39     ` Jean-Claude Rostaing
@ 2018-04-02 18:19       ` Jere
  2018-04-02 18:50         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 43+ messages in thread
From: Jere @ 2018-04-02 18:19 UTC (permalink / raw)


On Sunday, April 1, 2018 at 7:39:19 PM UTC-4, Jean-Claude Rostaing wrote:
> Ok, now I know why what I wanted to do was impossible. To store an object into an accessor or whatever, or to create it with allocator, with only a given "value" of this limited type, you need to COPY this value, whatever you do. Which goes against the very idea of limited type.
> I feel more intelligent thanks to that...
> And I know why though ITEM_TYPE is indefinite limited, you can only translate from its POINTER to a smart pointer, never directly from a value of that limited type.

Something else unrelated to your question, but that I just noticed: Assuming
you could have gotten a list definition that you were happy with, there is
still a very serious problem with it.  Doubly linked lists (ones that use
both Next and Prev/Pred) are susceptible to "circular references" when using
reference counting smart pointers.  You would need to use a weak reference
based smart pointer for one of the two (either Next or Prev/Pred, whichever
you prefer).

-- very simple/silly example
type Node is
   Value : Item_Type;
   Next  : Smart_Pointer_Type;
   Prev  : Weak_Smart_Pointer_Type;
end Node;

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

* Re: limited agregate and limited components default initialization
  2018-04-02 18:19       ` Jere
@ 2018-04-02 18:50         ` Dmitry A. Kazakov
  2018-04-02 19:46           ` Jere
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-02 18:50 UTC (permalink / raw)


On 2018-04-02 20:19, Jere wrote:

> Something else unrelated to your question, but that I just noticed: Assuming
> you could have gotten a list definition that you were happy with, there is
> still a very serious problem with it.  Doubly linked lists (ones that use
> both Next and Prev/Pred) are susceptible to "circular references" when using
> reference counting smart pointers.  You would need to use a weak reference
> based smart pointer for one of the two (either Next or Prev/Pred, whichever
> you prefer).
> 
> -- very simple/silly example
> type Node is
>     Value : Item_Type;
>     Next  : Smart_Pointer_Type;
>     Prev  : Weak_Smart_Pointer_Type;
> end Node;

This is still circular. Weak/strong references work only in hierarchical 
structures. If a doubly-linked list must deploy them then it should be 
the head holding references to all nodes. It does not make much sense 
though.

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


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

* Re: limited agregate and limited components default initialization
  2018-04-02 18:50         ` Dmitry A. Kazakov
@ 2018-04-02 19:46           ` Jere
  2018-04-02 19:59             ` Dmitry A. Kazakov
  2018-04-03  1:27             ` Dennis Lee Bieber
  0 siblings, 2 replies; 43+ messages in thread
From: Jere @ 2018-04-02 19:46 UTC (permalink / raw)


On Monday, April 2, 2018 at 2:51:00 PM UTC-4, Dmitry A. Kazakov wrote:
> On 2018-04-02 20:19, Jere wrote:
> 
> > Something else unrelated to your question, but that I just noticed: Assuming
> > you could have gotten a list definition that you were happy with, there is
> > still a very serious problem with it.  Doubly linked lists (ones that use
> > both Next and Prev/Pred) are susceptible to "circular references" when using
> > reference counting smart pointers.  You would need to use a weak reference
> > based smart pointer for one of the two (either Next or Prev/Pred, whichever
> > you prefer).
> > 
> > -- very simple/silly example
> > type Node is
> >     Value : Item_Type;
> >     Next  : Smart_Pointer_Type;
> >     Prev  : Weak_Smart_Pointer_Type;
> > end Node;
> 
> This is still circular. Weak/strong references work only in hierarchical 
> structures. If a doubly-linked list must deploy them then it should be 
> the head holding references to all nodes. It does not make much sense 
> though.
> 
Nope, not circular at all unless you connect Tail to Head (which isn't
the normal use case). The List type would hold a smart pointer to the
head node.  Been working flawlessly for over a decade now with no
circular references.


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

* Re: limited agregate and limited components default initialization
  2018-04-02 19:46           ` Jere
@ 2018-04-02 19:59             ` Dmitry A. Kazakov
  2018-04-02 21:03               ` Jean-Claude Rostaing
  2018-04-03  1:27             ` Dennis Lee Bieber
  1 sibling, 1 reply; 43+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-02 19:59 UTC (permalink / raw)


On 2018-04-02 21:46, Jere wrote:
> On Monday, April 2, 2018 at 2:51:00 PM UTC-4, Dmitry A. Kazakov wrote:
>> On 2018-04-02 20:19, Jere wrote:
>>
>>> Something else unrelated to your question, but that I just noticed: Assuming
>>> you could have gotten a list definition that you were happy with, there is
>>> still a very serious problem with it.  Doubly linked lists (ones that use
>>> both Next and Prev/Pred) are susceptible to "circular references" when using
>>> reference counting smart pointers.  You would need to use a weak reference
>>> based smart pointer for one of the two (either Next or Prev/Pred, whichever
>>> you prefer).
>>>
>>> -- very simple/silly example
>>> type Node is
>>>      Value : Item_Type;
>>>      Next  : Smart_Pointer_Type;
>>>      Prev  : Weak_Smart_Pointer_Type;
>>> end Node;
>>
>> This is still circular. Weak/strong references work only in hierarchical
>> structures. If a doubly-linked list must deploy them then it should be
>> the head holding references to all nodes. It does not make much sense
>> though.
>>
> Nope, not circular at all unless you connect Tail to Head (which isn't
> the normal use case).

Usually I do, it makes operations faster and easier because links are 
never null. I can even have not-null constraint on the links.

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

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

* Re: limited agregate and limited components default initialization
  2018-04-02 19:59             ` Dmitry A. Kazakov
@ 2018-04-02 21:03               ` Jean-Claude Rostaing
  2018-04-03  8:14                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-02 21:03 UTC (permalink / raw)


> Usually I do, it makes operations faster and easier because links are 
> never null. I can even have not-null constraint on the links.
Clever ! I never thought about it.
I know about weak references. I read about it. I simply thought I'm not smart enough yet to tackle the issue.


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

* Re: limited agregate and limited components default initialization
  2018-04-02 11:25           ` Jean-Claude Rostaing
  2018-04-02 12:11             ` Dmitry A. Kazakov
  2018-04-02 12:15             ` Jean-Claude Rostaing
@ 2018-04-02 21:37             ` Randy Brukardt
  2018-04-03 17:01               ` Jeffrey R. Carter
  2 siblings, 1 reply; 43+ messages in thread
From: Randy Brukardt @ 2018-04-02 21:37 UTC (permalink / raw)


Yes, I believe these two should work the same. (I'm not trying to figure out 
which is wrong.) I suggest a bug report... - Randy.

"Jean-Claude Rostaing" <00120260a@gmail.com> wrote in message 
news:d83d9dd1-3674-4299-ac9c-1bf5862ae0e2@googlegroups.com...
> It works, so much for "impossible" dmitry.
>
> I probably read before the implementation you mentioned, I don't remember 
> exactly. I saw something strange writing this. Shouldn't the expression 
> function
> function GET (Pointer : Pointer_Type) return Accessor_Type is
>     (if Pointer.Pointer = null or else POINTER.Pointer.Value = null then 
> raise EXC_NULL_POINTER_ACCESS
>      else ACCESSOR_TYPE'(Data_Link => Pointer.Pointer.Value));
> be strictly equivalent to
> function GET (Pointer : Pointer_Type) return Accessor_Type is
>   begin
>      if Pointer.Pointer = null or else POINTER.Pointer.Value = null then 
> raise EXC_NULL_POINTER_ACCESS;
>      else
>         return ACCESSOR_TYPE'(Data_Link => Pointer.Pointer.Value);
>      end if;
>   end GET;
> ? Yet no, the second is fine, the second raises at run time
> raised CONSTRAINT_ERROR : pointers.adb:20 discriminant check failed 


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

* Re: limited agregate and limited components default initialization
  2018-04-01 23:36   ` Jean-Claude Rostaing
  2018-04-01 23:39     ` Jean-Claude Rostaing
@ 2018-04-02 22:39     ` Robert I. Eachus
  1 sibling, 0 replies; 43+ messages in thread
From: Robert I. Eachus @ 2018-04-02 22:39 UTC (permalink / raw)


On 4/1/2018 7:36 PM, Jean-Claude Rostaing wrote:
> Ok, now I know why what I wanted to do was impossible. To store an object into an accessor or whatever, or to create it with allocator, with only a given "value" of this limited type, you need to COPY this value, whatever you do. Which goes against the very idea of limited type.
> I feel more intelligent thanks to that...
> 
There is a messy but workable solution.  Create (in the private part or 
package body) a non-limited type which has all the non-limited stuff 
from your limited type.   Call it Foo.  Now you can create an object of 
type Foo initialize it however you want, and then create the limited 
object with an aggregate containing Foo.

Why messy? You have to add .Foo all over the place.  But it works.  (Of 
course if there are unconstrained limited components, you may be hosed.)

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

* Re: limited agregate and limited components default initialization
  2018-04-02 19:46           ` Jere
  2018-04-02 19:59             ` Dmitry A. Kazakov
@ 2018-04-03  1:27             ` Dennis Lee Bieber
  1 sibling, 0 replies; 43+ messages in thread
From: Dennis Lee Bieber @ 2018-04-03  1:27 UTC (permalink / raw)


On Mon, 2 Apr 2018 12:46:58 -0700 (PDT), Jere <jhb.chat@gmail.com>
declaimed the following:


>Nope, not circular at all unless you connect Tail to Head (which isn't
>the normal use case). The List type would hold a smart pointer to the
>head node.  Been working flawlessly for over a decade now with no
>circular references.

	Don't explore the AmigaOS internals then... Much of it relied on
doubly-linked lists with the tail pointing back to the list header node
(and often in priority order too -- for things like blocked/ready
processes).


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/ 

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

* Re: limited agregate and limited components default initialization
  2018-04-02 21:03               ` Jean-Claude Rostaing
@ 2018-04-03  8:14                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 43+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-03  8:14 UTC (permalink / raw)


On 02/04/2018 23:03, Jean-Claude Rostaing wrote:
>> Usually I do, it makes operations faster and easier because links are
>> never null. I can even have not-null constraint on the links.
> Clever ! I never thought about it.
> I know about weak references. I read about it. I simply thought I'm not smart enough yet to tackle the issue.

You must. There are lots of cases where circular strong references must 
be broken, weak reference is a way. Other cases are when you don't want 
to lock the referenced object. Consider monitoring a file. The monitor 
would hold a weak reference to the file to allow file deletion.

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


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

* Re: limited agregate and limited components default initialization
  2018-04-02 21:37             ` Randy Brukardt
@ 2018-04-03 17:01               ` Jeffrey R. Carter
  0 siblings, 0 replies; 43+ messages in thread
From: Jeffrey R. Carter @ 2018-04-03 17:01 UTC (permalink / raw)


> "Jean-Claude Rostaing" <00120260a@gmail.com> wrote in message
> news:d83d9dd1-3674-4299-ac9c-1bf5862ae0e2@googlegroups.com...
>
> Shouldn't the expression
> function
> function GET (Pointer : Pointer_Type) return Accessor_Type is
>      (if Pointer.Pointer = null or else POINTER.Pointer.Value = null then
> raise EXC_NULL_POINTER_ACCESS
>       else ACCESSOR_TYPE'(Data_Link => Pointer.Pointer.Value));
> be strictly equivalent to
> function GET (Pointer : Pointer_Type) return Accessor_Type is
>    begin
>       if Pointer.Pointer = null or else POINTER.Pointer.Value = null then
> raise EXC_NULL_POINTER_ACCESS;
>       else
>          return ACCESSOR_TYPE'(Data_Link => Pointer.Pointer.Value);
>       end if;
>    end GET;

Technically, the expression function is equivalent to

function Get (Pointer : Pointer_Type) return Accessor_Type is
begin
    return (if Pointer.Pointer = null or else POINTER.Pointer.Value = null then
               raise EXC_NULL_POINTER_ACCESS
            else ACCESSOR_TYPE'(Data_Link => Pointer.Pointer.Value));
end Get;

so it would be interesting to see what that does. I don't see any reason why 
your non-expression version wouldn't also be equivalent, too, though.

-- 
Jeff Carter
"[A] brilliant military career that after thirty
years catapulted him to the rank of corporal."
Take the Money and Run
138


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

* Re: limited agregate and limited components default initialization
  2018-03-31 23:36 limited agregate and limited components default initialization Jean-Claude Rostaing
                   ` (2 preceding siblings ...)
  2018-04-01 22:52 ` Jean-Claude Rostaing
@ 2018-04-03 18:18 ` Jean-Claude Rostaing
  2018-04-03 18:28   ` Jean-Claude Rostaing
                     ` (2 more replies)
  3 siblings, 3 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-03 18:18 UTC (permalink / raw)


Talking about limited aggregates, how to make the exemple below with protected types work ? It should be pretty much the same as what I already did, yet...
package P is
   type Essai (<>) is limited  private;
   function Constructor (v: Natural) return  ESSAI;
   procedure CHANGE (Obj: Essai; V: Natural);
private
   protected type ESSAI (D1: Natural) is 
      procedure CHANGE (V: Natural);
   private
      Private_var: Natural := D1; 
   end Essai;
end P;

package BODY P is
   -- procedure change(Obj: Essai; V: natural) renames ESSAI.CHANGE;
   procedure CHANGE (Obj: ESSAI; V: NATURAL) is
   begin
      OBJ.CHANGE(V); -- 5
   end CHANGE;
   function CONSTRUCTOR ( V : NATURAL) return ESSAI is
     (Essai(D1 => V)); -- 9

   protected body Essai is
      procedure CHANGE (V: natural) is
      begin
         PRIVATE_VAR := V;
      end change;
   end Essai;
end P;

I get
p.adb:5:10: prefix of protected procedure or entry call must be variable
p.adb:9:14: invalid prefix in call

Actually, I wanted CHANGE to be a renaming of Change, but since Essai here behave more like a package, the protected operation doesn't its protected object as an argument, so the profile wouldn't be the same, so a renaming can only point to a specific task/protect object's entry.

I want to force people to use a constructor on any object of ESSAI type through setting its discriminants. Discriminants who would serve to set the default value with the constructor, so they must be hidden from the user.

I must confess I never used anything protected types before... I thought the use would be more intuitive ?

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

* Re: limited agregate and limited components default initialization
  2018-04-03 18:18 ` Jean-Claude Rostaing
@ 2018-04-03 18:28   ` Jean-Claude Rostaing
  2018-04-03 19:18   ` Jeffrey R. Carter
  2018-04-04  2:18   ` Jere
  2 siblings, 0 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-03 18:28 UTC (permalink / raw)


I tested your version Jeffrey, it failed too.
that line "return (if Pointer.Pointer = null or else POINTER.Pointer.Value = null then" is the culprit.
So it's not specific to expression functions, it seems.

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

* Re: limited agregate and limited components default initialization
  2018-04-03 18:18 ` Jean-Claude Rostaing
  2018-04-03 18:28   ` Jean-Claude Rostaing
@ 2018-04-03 19:18   ` Jeffrey R. Carter
  2018-04-03 19:25     ` Jean-Claude Rostaing
  2018-04-04  2:18   ` Jere
  2 siblings, 1 reply; 43+ messages in thread
From: Jeffrey R. Carter @ 2018-04-03 19:18 UTC (permalink / raw)


On 04/03/2018 08:18 PM, Jean-Claude Rostaing wrote:
> 
> p.adb:5:10: prefix of protected procedure or entry call must be variable

Obj should be mode "in out".

> p.adb:9:14: invalid prefix in call

I can't say I've ever tried to have a function return a protected type. I think 
you'll need to do

begin
    return R : Essai (D1 => V);
end Essai;

But I think it would be better in this case to expose the discriminant:

type Essai (D1 : Natural) is limited private;

Then clients have to provide the value they would pass to Constructor as the 
discriminant:

E : Essai (D1 => V);

which does what you want and is simpler.

-- 
Jeff Carter
"[A] brilliant military career that after thirty
years catapulted him to the rank of corporal."
Take the Money and Run
138

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

* Re: limited agregate and limited components default initialization
  2018-04-03 19:18   ` Jeffrey R. Carter
@ 2018-04-03 19:25     ` Jean-Claude Rostaing
  2018-04-03 20:12       ` Jeffrey R. Carter
  0 siblings, 1 reply; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-03 19:25 UTC (permalink / raw)


Oh thanks ! Yes, I forgot "in out", but since the internal is changed it makes sense.
Your exemple is simpler, yes, but it allows declaration of unitialized objects. I want to force the user to use a constructor, which might do extremely complicated computations based on the environment, and set also arbitrarily complicated discriminants, all things the user doesn't have to know about :-)

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

* Re: limited agregate and limited components default initialization
  2018-04-03 19:25     ` Jean-Claude Rostaing
@ 2018-04-03 20:12       ` Jeffrey R. Carter
  2018-04-03 22:37         ` Jean-Claude Rostaing
  0 siblings, 1 reply; 43+ messages in thread
From: Jeffrey R. Carter @ 2018-04-03 20:12 UTC (permalink / raw)


On 04/03/2018 09:25 PM, Jean-Claude Rostaing wrote:
> Your exemple is simpler, yes, but it allows declaration of unitialized objects.

In the specific example which you presented, my version did not allow declaring 
uninitialized objects, since all initialization was based on the discriminant, 
and the client had to supply a discriminant. In more complex cases it may be 
necessary to take other steps to ensure that initialization occurs. Unknown 
discriminants and a New_Thing function are one way to do that.

-- 
Jeff Carter
"[A] brilliant military career that after thirty
years catapulted him to the rank of corporal."
Take the Money and Run
138

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

* Re: limited agregate and limited components default initialization
  2018-04-03 20:12       ` Jeffrey R. Carter
@ 2018-04-03 22:37         ` Jean-Claude Rostaing
  0 siblings, 0 replies; 43+ messages in thread
From: Jean-Claude Rostaing @ 2018-04-03 22:37 UTC (permalink / raw)


Sorry, my bad.

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

* Re: limited agregate and limited components default initialization
  2018-04-03 18:18 ` Jean-Claude Rostaing
  2018-04-03 18:28   ` Jean-Claude Rostaing
  2018-04-03 19:18   ` Jeffrey R. Carter
@ 2018-04-04  2:18   ` Jere
  2 siblings, 0 replies; 43+ messages in thread
From: Jere @ 2018-04-04  2:18 UTC (permalink / raw)


On Tuesday, April 3, 2018 at 2:18:18 PM UTC-4, Jean-Claude Rostaing wrote:
> Talking about limited aggregates, how to make the exemple below with protected types work ? It should be pretty much the same as what I already did, yet...
> package P is
>    type Essai (<>) is limited  private;
>    function Constructor (v: Natural) return  ESSAI;
>    procedure CHANGE (Obj: Essai; V: Natural);
> private
>    protected type ESSAI (D1: Natural) is 
>       procedure CHANGE (V: Natural);
>    private
>       Private_var: Natural := D1; 
>    end Essai;
> end P;
> 
> package BODY P is
>    -- procedure change(Obj: Essai; V: natural) renames ESSAI.CHANGE;
>    procedure CHANGE (Obj: ESSAI; V: NATURAL) is
>    begin
>       OBJ.CHANGE(V); -- 5
>    end CHANGE;
>    function CONSTRUCTOR ( V : NATURAL) return ESSAI is
>      (Essai(D1 => V)); -- 9
> 
>    protected body Essai is
>       procedure CHANGE (V: natural) is
>       begin
>          PRIVATE_VAR := V;
>       end change;
>    end Essai;
> end P;
> 
> I get
> p.adb:5:10: prefix of protected procedure or entry call must be variable
> p.adb:9:14: invalid prefix in call
> 
> Actually, I wanted CHANGE to be a renaming of Change, but since Essai here behave more like a package, the protected operation doesn't its protected object as an argument, so the profile wouldn't be the same, so a renaming can only point to a specific task/protect object's entry.
> 
> I want to force people to use a constructor on any object of ESSAI type through setting its discriminants. Discriminants who would serve to set the default value with the constructor, so they must be hidden from the user.
> 
> I must confess I never used anything protected types before... I thought the use would be more intuitive ?

As an alternative.  If you end up needing to handle protected types without
discriminants, you can use a private implementation type and composition:

    package P is
       type Essai (<>) is limited private;
       function Constructor (v: Natural) return ESSAI;
       procedure CHANGE (Obj: in out Essai; V: Natural) with Inline;
    private
    
       -- Internal implementation type
       protected type ESSAI_Impl  is
          procedure CHANGE (V: Natural);
       private
          Private_var: Natural := 0;
       end Essai_Impl;
       
       -- new wrapper type
       type Essai is limited record
          Impl : Essai_Impl;
       end record;
    end P;
    
    package BODY P is
    
       procedure CHANGE (Obj: in out ESSAI; V: NATURAL) is
       begin
          OBJ.Impl.CHANGE(V); -- 5
       end CHANGE;
       
       function CONSTRUCTOR ( V : NATURAL) return ESSAI is
       begin
          -- Can use aggregate to create the wrapper type
          return Result : Essai := (others => <>) do
             Result.Impl.CHANGE(V);  --now initialize the value
          end return;
       end CONSTRUCTOR;
    
       protected body Essai_Impl is
       
          procedure CHANGE (V: natural) is
          begin
             PRIVATE_VAR := V;
          end change;
          
       end Essai_Impl;
       
    end P; 



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

* Re: limited agregate and limited components default initialization
  2018-04-02  3:44         ` Randy Brukardt
  2018-04-02 11:25           ` Jean-Claude Rostaing
@ 2018-04-05 10:27           ` AdaMagica
  1 sibling, 0 replies; 43+ messages in thread
From: AdaMagica @ 2018-04-05 10:27 UTC (permalink / raw)


Am Montag, 2. April 2018 05:44:50 UTC+2 schrieb Randy Brukardt:
> It won't always work directly. The implicit dereference usually needs to be 
> a separate (helper) object from the smart pointer. I believe Christophe 
> Grein has a working implementation (but I forget the link).

I did not follow closely this discussion and do not know whether this will help, but since I was mentioned, here's the link:

http://www.christ-usch-grein.homepage.t-online.de/Ada/Smart_Pointers.html


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

end of thread, other threads:[~2018-04-05 10:27 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-31 23:36 limited agregate and limited components default initialization Jean-Claude Rostaing
2018-04-01  0:52 ` Jere
2018-04-01  1:12   ` Jere
2018-04-01  1:16   ` Jean-Claude Rostaing
2018-04-01  1:34     ` Jere
2018-04-01  2:07       ` Jean-Claude Rostaing
2018-04-01  2:40         ` Jere
2018-04-01  2:54           ` Jere
2018-04-01  3:14         ` Jere
2018-04-01  3:31           ` Jere
2018-04-01  9:32         ` Jacob Sparre Andersen
2018-04-01 12:58           ` Jean-Claude Rostaing
2018-04-01 13:33 ` Dmitry A. Kazakov
2018-04-01 15:46   ` Jean-Claude Rostaing
2018-04-01 15:53     ` Jean-Claude Rostaing
2018-04-01 15:54       ` Jean-Claude Rostaing
2018-04-01 21:31       ` Dmitry A. Kazakov
2018-04-02  3:44         ` Randy Brukardt
2018-04-02 11:25           ` Jean-Claude Rostaing
2018-04-02 12:11             ` Dmitry A. Kazakov
2018-04-02 12:15             ` Jean-Claude Rostaing
2018-04-02 21:37             ` Randy Brukardt
2018-04-03 17:01               ` Jeffrey R. Carter
2018-04-05 10:27           ` AdaMagica
2018-04-02  3:42     ` Randy Brukardt
2018-04-01 22:52 ` Jean-Claude Rostaing
2018-04-01 23:36   ` Jean-Claude Rostaing
2018-04-01 23:39     ` Jean-Claude Rostaing
2018-04-02 18:19       ` Jere
2018-04-02 18:50         ` Dmitry A. Kazakov
2018-04-02 19:46           ` Jere
2018-04-02 19:59             ` Dmitry A. Kazakov
2018-04-02 21:03               ` Jean-Claude Rostaing
2018-04-03  8:14                 ` Dmitry A. Kazakov
2018-04-03  1:27             ` Dennis Lee Bieber
2018-04-02 22:39     ` Robert I. Eachus
2018-04-03 18:18 ` Jean-Claude Rostaing
2018-04-03 18:28   ` Jean-Claude Rostaing
2018-04-03 19:18   ` Jeffrey R. Carter
2018-04-03 19:25     ` Jean-Claude Rostaing
2018-04-03 20:12       ` Jeffrey R. Carter
2018-04-03 22:37         ` Jean-Claude Rostaing
2018-04-04  2:18   ` Jere

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