comp.lang.ada
 help / color / Atom feed
* Proposal: Auto-allocation of Indefinite Objects
@ 2020-04-03 22:48 Stephen Davies
  2020-04-03 23:45 ` Stephen Leake
                   ` (4 more replies)
  0 siblings, 5 replies; 47+ messages in thread
From: Stephen Davies @ 2020-04-03 22:48 UTC (permalink / raw)


Firstly, apologies if this has already been discussed or,
more likely, if it's a really stupid idea for some reason
that I haven't thought of.

My proposal is that it should (sometimes?) be possible to declare
objects of indefinite types such as String and have the compiler
automatically declare the space for them without the programmer
having to resort to access types.

Benefits:

1. Easier, especially for newbies/students.
2. Safer due to reduced use of access types.
3. Remove the need to have definite and indefinite verions of generic units.

It is the 3rd reason that initially got me thinking about this.
It seems excessive to have two versions of packages just because
one version can say "Node.Item := New_Item;" but the other has to say
"Node.Item_Ptr := new Element_Type'(New_Item);".

It's probably not a good idea for auto-allocation to be the default
behaviour, so I suggest something like:

   type Node_Type is record
      Item : new Element_Type;
      Prev : Node_Ptr_Type;
      Next : Node_Ptr_Type;
   end record;

If Element_Type is a definite type in the instantiation then
Node.Item will be a normal object of that type. Otherwise, it is
implemented as a pointer but the code still treats it as an object.
The target of the pointer is allocated on assignment of the object.
The pointer cannot be copied to any other object. Assignments of the
whole record will perform a deep-copy of the auto-allocated component.
The target of the Node.Item pointer can be auto-deallocated when Node
goes out of scope or is deallocated.

Ok, I've probably missed something obvious and have been wasting my
time, but at least I've got plenty of time to waste at the moment. 

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-04-03 22:48 Proposal: Auto-allocation of Indefinite Objects Stephen Davies
@ 2020-04-03 23:45 ` Stephen Leake
  2020-04-04 10:54   ` Jeffrey R. Carter
  2020-04-04  8:31 ` Dmitry A. Kazakov
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 47+ messages in thread
From: Stephen Leake @ 2020-04-03 23:45 UTC (permalink / raw)


On Friday, April 3, 2020 at 3:48:43 PM UTC-7, Stephen Davies wrote:
> Firstly, apologies if this has already been discussed or,
> more likely, if it's a really stupid idea for some reason
> that I haven't thought of.
> 
> My proposal is that it should (sometimes?) be possible to declare
> objects of indefinite types such as String and have the compiler
> automatically declare the space for them without the programmer
> having to resort to access types.

declare
   Foo : String := ...;
begin
   ...
end;

Foo is allocated on the stack; size is taken from the initialization expression.

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

declare
   Foo : Unbounded_String; -- empty
begin
   Foo := To_Unbounded ("hi"); -- allocated on the heap
   Foo := Foo & To_Unbounded ("bye"); -- allocation grows
end;
-- deallocated.

-- Stephe

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-04-03 22:48 Proposal: Auto-allocation of Indefinite Objects Stephen Davies
  2020-04-03 23:45 ` Stephen Leake
@ 2020-04-04  8:31 ` Dmitry A. Kazakov
  2020-07-27  7:47 ` Yannick Moy
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-04-04  8:31 UTC (permalink / raw)


On 2020-04-04 00:48, Stephen Davies wrote:

> It is the 3rd reason that initially got me thinking about this.
> It seems excessive to have two versions of packages just because
> one version can say "Node.Item := New_Item;" but the other has to say
> "Node.Item_Ptr := new Element_Type'(New_Item);".

This is another issue, IMO. The language should support interface 
inheritance:

    type Node_Item_Inteface is ...;

    type Static_Node_Item is
       new Node_Item_Inteface with record ...

    type Dynamic_Node_Item is
       new Node_Item_Inteface with access Some_Implementation;

Implementation of an interface per access type.

> It's probably not a good idea for auto-allocation to be the default
> behaviour, so I suggest something like:
> 
>     type Node_Type is record
>        Item : new Element_Type;
>        Prev : Node_Ptr_Type;
>        Next : Node_Ptr_Type;
>     end record;
> 
> If Element_Type is a definite type in the instantiation then
> Node.Item will be a normal object of that type. Otherwise, it is
> implemented as a pointer but the code still treats it as an object.
> The target of the pointer is allocated on assignment of the object.
> The pointer cannot be copied to any other object. Assignments of the
> whole record will perform a deep-copy of the auto-allocated component.
> The target of the Node.Item pointer can be auto-deallocated when Node
> goes out of scope or is deallocated.
> 
> Ok, I've probably missed something obvious and have been wasting my
> time, but at least I've got plenty of time to waste at the moment.

This looks interesting to me. There is a huge number of cases I am using 
this schema, especially when Item is initialized once.

The major advantage is of course in having a plain String instead of 
Unbounded_String. No conversions, no space/time penalties. I refrain 
using Unbounded_String as much as possible.

Also there must be a possibility to specify the pool of Item. I 
frequently place things like Node_Type into an arena pool, soI want the 
string going there as well. Another case is marshaling such objects, so 
that the body of Item would not be left behind.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-04-03 23:45 ` Stephen Leake
@ 2020-04-04 10:54   ` Jeffrey R. Carter
  2020-04-04 20:55     ` Stephen Davies
  0 siblings, 1 reply; 47+ messages in thread
From: Jeffrey R. Carter @ 2020-04-04 10:54 UTC (permalink / raw)


On 4/4/20 1:45 AM, Stephen Leake wrote:
> 
> with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
> 
> declare
>     Foo : Unbounded_String; -- empty
> begin
>     Foo := To_Unbounded ("hi"); -- allocated on the heap
>     Foo := Foo & To_Unbounded ("bye"); -- allocation grows

Foo := Foo & "bye";

Those should be To_Unbounded_String;

For an issue related to the OP's idea, consider

with System;

procedure Boom is
    type Very_Large_Item is ...;
    type Very_Large_Index is mod System.Max_Binary_Modulus;
    type Very_Large_List is array (Very_Large_Index range <>) of Very_Large_Item;

    Last : constant := ...;

    List : Very_Large_List (0 .. Last);
begin -- Boom
    ... -- Do some thing useful with List
end Boom;

There exists a value N > 0 such that Last = N works and Last = N + 1 results in 
Storage_Error. The actual value of N may vary depending on the compiler, target, 
and the actual machine on which the program is executed.

If you want to handle a List with Last > N, you have to make it an access to 
Very_Large_List unless you care where it is allocated. There is still a value M 
which will result in Storage_Error, but on most machines where you'd try to 
process such a large object, M >> N because on such machines the heap is much 
larger than the stack. Implicit dereferencing makes this change less painful 
than it would be without implicit dereferencing, but there are still usually 
places where explicit dereferencing will be needed, so there is still some pain 
involved even though you don't care where the object is allocated.

It would be nice if there were a compiler option where objects that don't fit on 
the stack would be automatically allocated on the heap, and automatically 
deallocated when they go out of scope.

Similar arguments can be made for a compiler option where all numeric types 
would be accepted, with some implemented in terms of the compiler's ability to 
calculate static expressions exactly, rather than the user having to switch from 
a numeric type to an unbounded-number pkg. This has the added value that such 
pkgs usually lose the automated checks that numeric types have.

All of these issues have been around for some time, and the ARG is aware of them 
and has chosen to take no action. That seems unlikely to change.

-- 
Jeff Carter
"I'm a vicious jungle beast!"
Play It Again, Sam
131

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-04-04 10:54   ` Jeffrey R. Carter
@ 2020-04-04 20:55     ` Stephen Davies
  0 siblings, 0 replies; 47+ messages in thread
From: Stephen Davies @ 2020-04-04 20:55 UTC (permalink / raw)



On 2020-04-03, Stephen Davies wrote: 
>>
>> Item : New String; [ill-thought-out proposal]

On 2020-04-04, Stephen Leake wrote: 
> 
> [Ada-101 stuff ;-)]

On 2020-04-04, Dmitry A. Kazakov wrote: 
> 
> This looks interesting to me. There is a huge number of cases I
> am using this schema, especially when Item is initialized once. 

Woohoo, I'm not a complete idiot.

On 2020-04-04, Jeffrey R. Carter wrote: 
> 
> the ARG is aware of them and has chosen to take no action.
> That seems unlikely to change. 

Oh. :-(

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-04-03 22:48 Proposal: Auto-allocation of Indefinite Objects Stephen Davies
  2020-04-03 23:45 ` Stephen Leake
  2020-04-04  8:31 ` Dmitry A. Kazakov
@ 2020-07-27  7:47 ` Yannick Moy
  2020-07-27  9:21   ` J-P. Rosen
  2020-07-27 17:48   ` Brian Drummond
  2020-07-31  9:25 ` Stephen Davies
  2020-09-03  4:30 ` linda white
  4 siblings, 2 replies; 47+ messages in thread
From: Yannick Moy @ 2020-07-27  7:47 UTC (permalink / raw)


Hi Stephen,

On Saturday, April 4, 2020 at 12:48:43 AM UTC+2, Stephen Davies wrote:
> Firstly, apologies if this has already been discussed or, 
> more likely, if it's a really stupid idea for some reason 
> that I haven't thought of. 

Actually, that's something more and more of us would like to see.

> My proposal is that it should (sometimes?) be possible to declare 
> objects of indefinite types such as String and have the compiler 
> automatically declare the space for them without the programmer 
> having to resort to access types. 

I agree with the goal.

> Benefits: 
> 
> 1. Easier, especially for newbies/students. 
> 2. Safer due to reduced use of access types. 
> 3. Remove the need to have definite and indefinite versions of generic units. 

I agree with 2 only if we can combine this with safe handling of aliasing. It would be terrible to have such a feature lead to unsafe code if you somehow copy the pointer. Also, for strings that's possibly not the only change needed. What you'd like really is to be able to reassign the string to some larger/smaller string, like you do when using Unbounded_String.

On 2020-04-04, Jeffrey R. Carter wrote:
>
> the ARG is aware of them and has chosen to take no action.
> That seems unlikely to change.

On the other hand, AdaCore has launched a project to collect/discuss ideas/suggestions/problems regarding the evolution of Ada and SPARK: https://github.com/AdaCore/ada-spark-rfcs
Feel free to open an Issue there on that topic.

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-27  7:47 ` Yannick Moy
@ 2020-07-27  9:21   ` J-P. Rosen
  2020-07-27  9:49     ` Dmitry A. Kazakov
  2020-07-27 17:48   ` Brian Drummond
  1 sibling, 1 reply; 47+ messages in thread
From: J-P. Rosen @ 2020-07-27  9:21 UTC (permalink / raw)


Le 27/07/2020 à 09:47, Yannick Moy a écrit :
>> My proposal is that it should (sometimes?) be possible to declare 
>> objects of indefinite types such as String and have the compiler 
>> automatically declare the space for them without the programmer 
>> having to resort to access types. 
> I agree with the goal.
> 
You have it already. It's called Unbounded_String.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-27  9:21   ` J-P. Rosen
@ 2020-07-27  9:49     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-07-27  9:49 UTC (permalink / raw)


On 27/07/2020 11:21, J-P. Rosen wrote:
> Le 27/07/2020 à 09:47, Yannick Moy a écrit :
>>> My proposal is that it should (sometimes?) be possible to declare
>>> objects of indefinite types such as String and have the compiler
>>> automatically declare the space for them without the programmer
>>> having to resort to access types.
>> I agree with the goal.
>>
> You have it already. It's called Unbounded_String.

Not really.

1. Unbounded_String is a compromise needed when the string length change 
during its life. The great majority of cases allocate [and initialize] a 
string just once. [addressed to be the cases when using a discriminant 
does not work]

2. There is nothing for arrays that are not strings and for other 
indefinite types. E.g.:

    type Node_Type is record
       Item : new Element_Type'Class;
       Prev : Node_Ptr_Type;
       Next : Node_Ptr_Type;
    end record;

3. There is nothing for serialization and marshaling objects logically 
containing strings and other indefinite types.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-27  7:47 ` Yannick Moy
  2020-07-27  9:21   ` J-P. Rosen
@ 2020-07-27 17:48   ` Brian Drummond
  2020-07-27 20:02     ` Dmitry A. Kazakov
  2020-07-27 20:31     ` Jeffrey R. Carter
  1 sibling, 2 replies; 47+ messages in thread
From: Brian Drummond @ 2020-07-27 17:48 UTC (permalink / raw)


On Mon, 27 Jul 2020 00:47:30 -0700, Yannick Moy wrote:

>> My proposal is that it should (sometimes?) be possible to declare
>> objects of indefinite types such as String and have the compiler
>> automatically declare the space for them without the programmer having
>> to resort to access types.

In one sense we already have this ... in that we can do this in a Declare 
block, where stack allocation is a practical implementation.

But what about cases where (for whatever reason) we want it allocated on 
the heap?

In another sense we have it as JP Rosen said, for the specific example 
Unbounded_String.

Is there any way we could generalise the (storage, access and lifetime 
aspects of) Unbounded_String for unconstrained arrays and discriminated 
records in such a way that Unbounded_String can be a simple instantiation 
of one of these? 

But without the full flexibility (or overhead) of controlled types. So, 
somewhere in between, as:

1. Controlled type
|
---2.Unconstrained Array or Discriminated Record 
   |
   ---3. Unbounded String (instance of 2)

2) can be implemented internally using pointers, but externally appears 
to be a data object, just like Unbounded_String does, with similar 
semantics. 

-- Brian

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-27 17:48   ` Brian Drummond
@ 2020-07-27 20:02     ` Dmitry A. Kazakov
  2020-07-28 14:28       ` Brian Drummond
  2020-07-27 20:31     ` Jeffrey R. Carter
  1 sibling, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-07-27 20:02 UTC (permalink / raw)


On 27/07/2020 19:48, Brian Drummond wrote:

> 2) can be implemented internally using pointers, but externally appears
> to be a data object, just like Unbounded_String does, with similar
> semantics.

No, the point is that Unbounded_String is exactly opposite to what is 
required. In no case it should appear as an object of a different type!

Compare access to string P with unbounded string U:

    for I in P'Range loop -- This is OK
    P(J) := 'a' -- This is OK

Now would you do:

    To_String (U) (J) := 'a' -- Garbage!

What if the original object must be a class-wide object, task, protected 
object, limited object etc?

Ada's access types delegate all operations to the target object, except 
assignment. This is the key property that the proposal in my view must 
retain.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-27 17:48   ` Brian Drummond
  2020-07-27 20:02     ` Dmitry A. Kazakov
@ 2020-07-27 20:31     ` Jeffrey R. Carter
  1 sibling, 0 replies; 47+ messages in thread
From: Jeffrey R. Carter @ 2020-07-27 20:31 UTC (permalink / raw)


On 7/27/20 7:48 PM, Brian Drummond wrote:
> 
> Is there any way we could generalise the (storage, access and lifetime
> aspects of) Unbounded_String for unconstrained arrays and discriminated
> records in such a way that Unbounded_String can be a simple instantiation
> of one of these?

Ada.Strings.Unbounded can be considered a combination of 
Ada.Containers.Indefinite_Holders instantiated for String and 
Ada.Containers.Vectors instantiated with Positive and Character, with some 
additional operations added.

The To_String and To_Unbounded_String operations of Unbounded_String are similar 
to the Element and Replace_Element operations of Holder, which do not exist for 
Vector.

The indexed operations of Unbounded_String are similar to the indexed operations 
of Vector, which do not exist for Holder.

If Ada.Containers.Vectors had an additional generic formal type

    type Fixed is array (Index_Type range <>) of Element_Type;

and 2 new operations

    function To_Fixed (From : Vector) return Fixed;
    function To_Vector (From : Fixed) return Vector;

then we wouldn't need Ada.Strings.Unbounded.

-- 
Jeff Carter
"Blessed is just about anyone with a vested interest in the status quo."
Monty Python's Life of Brian
73

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-27 20:02     ` Dmitry A. Kazakov
@ 2020-07-28 14:28       ` Brian Drummond
  2020-07-28 14:59         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Brian Drummond @ 2020-07-28 14:28 UTC (permalink / raw)


On Mon, 27 Jul 2020 22:02:57 +0200, Dmitry A. Kazakov wrote:

> On 27/07/2020 19:48, Brian Drummond wrote:
> 
>> 2) can be implemented internally using pointers, but externally appears
>> to be a data object, just like Unbounded_String does, with similar
>> semantics.
> 
> No, the point is that Unbounded_String is exactly opposite to what is
> required. In no case it should appear as an object of a different type!
> 
> Compare access to string P with unbounded string U:
> 
>     for I in P'Range loop -- This is OK 
>        P(J) := 'a' -- This is OK
> 
> Now would you do:
> 
>     To_String (U) (J) := 'a' -- Garbage!

That wasn't the aspect of Unbounded I was getting at. I agree ... garbage.

What I meant was that Unbounded doesn't load New, dereferencing, 
deallocation etc onto the programmer, but hides the access details, and 
our indefinite type should do the same (the compiler can probably to a 
better job than the programmer anyway).

I'm suggesting something more like the C++ reference, signalling (perhaps 
by adding a reserved word "indefinite") that fixed size allocation won't 
work; and implementation is more in line with a controlled type but with 
system-provided Initialise,Adjust,Finalize providing the required 
operations (no need for the programmer to provide them).

A : String := "hello" -- a definite string
P : access String := new String'("hello");
Q : indefinite String := "hello";

... 
   begin
     for I in P'Range loop -- This is OK 
        P(J) := 'a'; -- This is OK
        Q(J) := 'a'; -- also OK. But index out of range would raise 
Constraint Error
...
     Q := "hello_world"; -- deallocates, allocates with new bounds
...
   end;    -- deallocate Q here.

It follows that "indefinite" cannot also be "aliased" unless we want to 
implement smart pointers. For simplicity I'd suggest disallowing "aliased 
indefinite" on the grounds that "access" can (should) be used instead.

Records (including tagged, class wide, discriminated) should work the 
same, but probably with shallow copy on assignment if they contain access 
types.

If there is no re-allocation (no different size assignment) the compiler 
is free to substitute direct (stack) storage instead of heap allocation 
and implicit access types. So for example instead of
   
   A constant String := "done";
 ...
   loop
      declare
         P : String := Get_Line;
      begin
         exit when P = A;
      end;
   end loop;

   A constant String := "done";
   Q : indefinite String;
 ...
   loop
      Q := Get_Line;
      exit when Q = A;
   end loop;

the implementation can be either an implicit declare block or an implicit 
access type. However, where Q has several reassignments within a block, 
and the compiler can't determine the size, an implicit access type must 
be used. (If it can, it can warn that "indefinite " is unnecessary).

> What if the original object must be a class-wide object, task, protected
> object, limited object etc?
> 
> Ada's access types delegate all operations to the target object, except
> assignment. This is the key property that the proposal in my view must
> retain.

Indefinite can also be applied to records (discriminated, class wide, etc) 
here the size is indeterminate and may vary on reassignment. Assignment 
would always be shallow copy (where the record contained access types).

-- Brian

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-28 14:28       ` Brian Drummond
@ 2020-07-28 14:59         ` Dmitry A. Kazakov
  2020-07-29 15:33           ` Brian Drummond
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-07-28 14:59 UTC (permalink / raw)


On 28/07/2020 16:28, Brian Drummond wrote:
> On Mon, 27 Jul 2020 22:02:57 +0200, Dmitry A. Kazakov wrote:
> 
>> On 27/07/2020 19:48, Brian Drummond wrote:
>>
>>> 2) can be implemented internally using pointers, but externally appears
>>> to be a data object, just like Unbounded_String does, with similar
>>> semantics.
>>
>> No, the point is that Unbounded_String is exactly opposite to what is
>> required. In no case it should appear as an object of a different type!
>>
>> Compare access to string P with unbounded string U:
>>
>>      for I in P'Range loop -- This is OK
>>         P(J) := 'a' -- This is OK
>>
>> Now would you do:
>>
>>      To_String (U) (J) := 'a' -- Garbage!
> 
> That wasn't the aspect of Unbounded I was getting at. I agree ... garbage.
> 
> What I meant was that Unbounded doesn't load New, dereferencing,
> deallocation etc onto the programmer, but hides the access details, and
> our indefinite type should do the same (the compiler can probably to a
> better job than the programmer anyway).
> 
> I'm suggesting something more like the C++ reference, signalling (perhaps
> by adding a reserved word "indefinite") that fixed size allocation won't
> work;

Equivalent of C++ reference in Ada is renaming.

  and implementation is more in line with a controlled type but with
> system-provided Initialise,Adjust,Finalize providing the required
> operations (no need for the programmer to provide them).
> 
> A : String := "hello" -- a definite string
> P : access String := new String'("hello");
> Q : indefinite String := "hello";

I think the keyword is misleading. Maybe this:

    Q : new String := "hello";

And I don't like initialization. It was a mistake to have limited 
return. The syntax must stress that all initialization is strictly 
in-place. No copies involved because the pool is fixed.

> ...
>     begin
>       for I in P'Range loop -- This is OK
>          P(J) := 'a'; -- This is OK
>          Q(J) := 'a'; -- also OK. But index out of range would raise
> Constraint Error
> ...
>       Q := "hello_world"; -- deallocates, allocates with new bounds
> ...
>     end;    -- deallocate Q here.

The rule could be "same pool" as of the container. In the case of a 
block, the pool is the stack. In the case of a record member, the pool 
is the pool of where the record itself is allocated. So that you could 
allocate all object in the same pool.

> It follows that "indefinite" cannot also be "aliased" unless we want to
> implement smart pointers. For simplicity I'd suggest disallowing "aliased
> indefinite" on the grounds that "access" can (should) be used instead.

It makes sense, but there are use cases for having it aliased:

    X : indefinite T;
    Y : indefinite S (X'Access); -- Access discriminant

> Records (including tagged, class wide, discriminated) should work the
> same, but probably with shallow copy on assignment if they contain access
> types.
> 
> If there is no re-allocation (no different size assignment) the compiler
> is free to substitute direct (stack) storage instead of heap allocation
> and implicit access types. So for example instead of
>     
>     A constant String := "done";
>   ...
>     loop
>        declare
>           P : String := Get_Line;
>        begin
>           exit when P = A;
>        end;
>     end loop;
> 
>     A constant String := "done";
>     Q : indefinite String;
>   ...
>     loop
>        Q := Get_Line;
>        exit when Q = A;
>     end loop;

I am not comfortable with the semantics of this and with possible 
implications too. I would keep it simple.

> the implementation can be either an implicit declare block or an implicit
> access type. However, where Q has several reassignments within a block,
> and the compiler can't determine the size, an implicit access type must
> be used. (If it can, it can warn that "indefinite " is unnecessary).
> 
>> What if the original object must be a class-wide object, task, protected
>> object, limited object etc?
>>
>> Ada's access types delegate all operations to the target object, except
>> assignment. This is the key property that the proposal in my view must
>> retain.
> 
> Indefinite can also be applied to records (discriminated, class wide, etc)
> here the size is indeterminate and may vary on reassignment. Assignment
> would always be shallow copy (where the record contained access types).

That would be inconsistent. IMO, it should be a deep copy, provided such 
a component would not make the type limited, of which I am not sure.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-28 14:59         ` Dmitry A. Kazakov
@ 2020-07-29 15:33           ` Brian Drummond
  2020-07-29 16:20             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Brian Drummond @ 2020-07-29 15:33 UTC (permalink / raw)


On Tue, 28 Jul 2020 16:59:09 +0200, Dmitry A. Kazakov wrote:

> On 28/07/2020 16:28, Brian Drummond wrote:
>> On Mon, 27 Jul 2020 22:02:57 +0200, Dmitry A. Kazakov wrote:
>> 
>>> On 27/07/2020 19:48, Brian Drummond wrote:
>>>
>>>> 2) can be implemented internally using pointers, but externally
>>>> appears to be a data object, just like Unbounded_String does, with
>>>> similar semantics.
>>>
>>> No, the point is that Unbounded_String is exactly opposite to what is
>>> required. In no case it should appear as an object of a different
>>> type!
>>>
>>> Compare access to string P with unbounded string U:
>>>
>>>      for I in P'Range loop -- This is OK
>>>         P(J) := 'a' -- This is OK
>>>
>>> Now would you do:
>>>
>>>      To_String (U) (J) := 'a' -- Garbage!
>> 
>> That wasn't the aspect of Unbounded I was getting at. I agree ...
>> garbage.
>> 
>> What I meant was that Unbounded doesn't load New, dereferencing,
>> deallocation etc onto the programmer, but hides the access details, and
>> our indefinite type should do the same (the compiler can probably to a
>> better job than the programmer anyway).
>> 
>> I'm suggesting something more like the C++ reference, signalling
>> (perhaps by adding a reserved word "indefinite") that fixed size
>> allocation won't work;
> 
> Equivalent of C++ reference in Ada is renaming.

OK. Not quite sure how complete the correspondence between reference and 
renaming is, but I can see similarities.

>> Q : indefinite String := "hello";
> 
> I think the keyword is misleading. Maybe this:
> 
>     Q : new String := "hello";

Not sure I like. The reader has to make the mental jump from seeing "new" 
to thinking of this as an indefinite type. There may be a better keyword, 
open to suggestions, but let's stick to indefinite for now.

> And I don't like initialization. 

Initialisation is unnecessary for indefinite String. It was only used in 
that example for similarity with previous strings A,P.

>>     begin
>>       for I in P'Range loop -- This is OK
>>          P(J) := 'a'; -- This is OK Q(J) := 'a'; -- also OK. But index
>>          out of range would raise
>> Constraint Error ...
>>       Q := "hello_world"; -- deallocates, allocates with new bounds
>> ...
>>     end;    -- deallocate Q here.
> 
> The rule could be "same pool" as of the container. In the case of a
> block, the pool is the stack. In the case of a record member, the pool
> is the pool of where the record itself is allocated. So that you could
> allocate all object in the same pool.

Looks like a good rule. Saves the compiler having to plant deallocations 
if the whole pool is to be de-allocated.
 
>> It follows that "indefinite" cannot also be "aliased" unless we want to
>> implement smart pointers. For simplicity I'd suggest disallowing
>> "aliased indefinite" on the grounds that "access" can (should) be used
>> instead.
> 
> It makes sense, but there are use cases for having it aliased:
> 
>     X : indefinite T;
      X : aliased indefinite T;
>     Y : indefinite S (X'Access); -- Access discriminant
As elsewhere, "aliased" indicates both to compiler and reader, that the 
rules are about to get more complicated. Specifically, if X is re-
allocated thanks to a different size assignment, all Y must be updated.

>>     A constant String := "done"; 
>>     Q : indefinite String;
>>   ...
>>     loop
>>        Q := Get_Line; 
>>        exit when Q = A;
>>     end loop;
> 
> I am not comfortable with the semantics of this and with possible
> implications too. I would keep it simple.

Interesting. Can you pin down some of that discomfort? It looks simple to 
me : 

"indefinite" indicates the size can vary (and the compiler knows whether 
it used the heap or stack), and in the absence of "aliased" we know there 
are no copies of the pointer (if heap). 

But of course my mind isn't wrapped round all the corner cases, and if 
you are uncomfortable, I'm probably missing a very good reason.

>> Indefinite can also be applied to records (discriminated, class wide,
>> etc)
>> here the size is indeterminate and may vary on reassignment. Assignment
>> would always be shallow copy (where the record contained access types).
> 
> That would be inconsistent. IMO, it should be a deep copy, provided such
> a component would not make the type limited, of which I am not sure.

Honest question : Inconsistent with what?
I suggested shallow copy just for simplicity, and for no (ahh) deeper 
reason. But again, I'm probably missing something.

Thank you for your thoughts. I don't know if this is worth developing 
into an AI.

-- Brian

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-29 15:33           ` Brian Drummond
@ 2020-07-29 16:20             ` Dmitry A. Kazakov
  2020-07-30 13:37               ` Stephen Davies
                                 ` (2 more replies)
  0 siblings, 3 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-07-29 16:20 UTC (permalink / raw)


On 29/07/2020 17:33, Brian Drummond wrote:
> On Tue, 28 Jul 2020 16:59:09 +0200, Dmitry A. Kazakov wrote:

>>>      A constant String := "done";
>>>      Q : indefinite String;
>>>    ...
>>>      loop
>>>         Q := Get_Line;
>>>         exit when Q = A;
>>>      end loop;
>>
>> I am not comfortable with the semantics of this and with possible
>> implications too. I would keep it simple.
> 
> Interesting. Can you pin down some of that discomfort? It looks simple to
> me :
> 
> "indefinite" indicates the size can vary (and the compiler knows whether
> it used the heap or stack), and in the absence of "aliased" we know there
> are no copies of the pointer (if heap).

I don't like compiler relocating objects. If the pool is a stack (or 
heap organized as a stack) it might be unable to do this.

In general, there are two close but not equivalent objectives one is 
handling indefinite components of records another is a transparent 
holder object integrated into the language (without generic mess).

Your use case is about the latter. My is rather the former.

I doubt it is possible to unite both objectives in a single AI.

>> That would be inconsistent. IMO, it should be a deep copy, provided such
>> a component would not make the type limited, of which I am not sure.
> 
> Honest question : Inconsistent with what?
> I suggested shallow copy just for simplicity, and for no (ahh) deeper
> reason. But again, I'm probably missing something.

If you make a shallow copy of

    type Node_Type is record
       Item : new Element_Type;
       Prev : Node_Ptr_Type;
       Next : Node_Ptr_Type;
    end record;

you create a dangling pointer should the original node disappear. A deep 
copy would create a new target for new Item.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-29 16:20             ` Dmitry A. Kazakov
@ 2020-07-30 13:37               ` Stephen Davies
  2020-07-30 14:23                 ` Dmitry A. Kazakov
  2020-07-30 17:04               ` Brian Drummond
  2020-08-10  0:31               ` Randy Brukardt
  2 siblings, 1 reply; 47+ messages in thread
From: Stephen Davies @ 2020-07-30 13:37 UTC (permalink / raw)


On Wednesday, 29 July 2020 at 17:20:24 UTC+1, Dmitry A. Kazakov wrote:
> If you make a shallow copy of
> type Node_Type is record 
> Item : new Element_Type; 
> Prev : Node_Ptr_Type; 
> Next : Node_Ptr_Type; 
> end record;
> you create a dangling pointer should the original node disappear. A deep 
> copy would create a new target for new Item.

I see my proposal is being debated again.
And Dmitry is arguing my case far better that I could, so I'll probably stay quiet.
(though maybe I should try to plant the idea of "Trim_Image" and "Trim_Width" into Dmitry's head ;-))

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-30 13:37               ` Stephen Davies
@ 2020-07-30 14:23                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-07-30 14:23 UTC (permalink / raw)


On 30/07/2020 15:37, Stephen Davies wrote:

> (though maybe I should try to plant the idea of "Trim_Image" and "Trim_Width" into Dmitry's head ;-))

My head is already filled with X'Image instead of T'Image(X), as stream 
attributes already are, with optional parameters for width, alignment, 
base, precision, sign, encoding (e.g. for using UTF-8 superscripts in 
the floating-point exponent).

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-29 16:20             ` Dmitry A. Kazakov
  2020-07-30 13:37               ` Stephen Davies
@ 2020-07-30 17:04               ` Brian Drummond
  2020-07-30 18:28                 ` Dmitry A. Kazakov
  2020-08-10  0:31               ` Randy Brukardt
  2 siblings, 1 reply; 47+ messages in thread
From: Brian Drummond @ 2020-07-30 17:04 UTC (permalink / raw)


On Wed, 29 Jul 2020 18:20:24 +0200, Dmitry A. Kazakov wrote:

> On 29/07/2020 17:33, Brian Drummond wrote:
>> On Tue, 28 Jul 2020 16:59:09 +0200, Dmitry A. Kazakov wrote:
> 
>>>>      A constant String := "done";
>>>>      Q : indefinite String;
>>>>    ...
>>>>      loop
>>>>         Q := Get_Line; exit when Q = A;
>>>>      end loop;
>>>
>>> I am not comfortable with the semantics of this and with possible
>>> implications too. I would keep it simple.
>> 
>> Interesting. Can you pin down some of that discomfort? It looks simple
>> to me :
>> 
>> "indefinite" indicates the size can vary (and the compiler knows
>> whether it used the heap or stack), and in the absence of "aliased" we
>> know there are no copies of the pointer (if heap).
> 
> I don't like compiler relocating objects. If the pool is a stack (or
> heap organized as a stack) it might be unable to do this.

Ah OK, I see it.

The compiler should be able to determine if (as in the loop above) the 
use of Q (the indefinite type) is equivalent to a Declare block (i.e. can 
be on the stack; new stack frame in each iteration; no relocation ever 
required) or not. 

If it cannot prove, it should assume not. In which case allocation is NOT 
on stack or heap so organised, and it knows before generating code that 
heap allocation and possible relocation is required. 

In this latter case the situation is no worse than if the programmers 
explicitly used an access type and handled the allocations and 
relocations and frees themselves, but without requiring that level of 
detail.
 
> In general, there are two close but not equivalent objectives one is
> handling indefinite components of records another is a transparent
> holder object integrated into the language (without generic mess).
> 
> Your use case is about the latter. My is rather the former.

If a record with even one indefinite component is an indefinite record, 
and therefore embedded in a transparent holder (I like that term), aren't 
they equivalent?

>> Honest question : Inconsistent with what?
>> I suggested shallow copy just for simplicity, and for no (ahh) deeper
>> reason. But again, I'm probably missing something.
> 
> If you make a shallow copy of
> 
>     type Node_Type is record
>        Item : new Element_Type;
>        Prev : Node_Ptr_Type; Next : Node_Ptr_Type;
>     end record;
> 
> you create a dangling pointer should the original node disappear. A deep
> copy would create a new target for new Item.

You are using "new" to signify Item is indefinite, I think?

But the problem is that Prev,Next are copies of the original Prev,Next 
pointers, so if the original Node_Type is then freed, they are dangling?

Thanks, this one I'll have to think about. 

-- Brian


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-30 17:04               ` Brian Drummond
@ 2020-07-30 18:28                 ` Dmitry A. Kazakov
  2020-08-10  0:39                   ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-07-30 18:28 UTC (permalink / raw)


On 30/07/2020 19:04, Brian Drummond wrote:
> On Wed, 29 Jul 2020 18:20:24 +0200, Dmitry A. Kazakov wrote:
> 
>> On 29/07/2020 17:33, Brian Drummond wrote:
>>> On Tue, 28 Jul 2020 16:59:09 +0200, Dmitry A. Kazakov wrote:
>>
>>>>>       A constant String := "done";
>>>>>       Q : indefinite String;
>>>>>     ...
>>>>>       loop
>>>>>          Q := Get_Line; exit when Q = A;
>>>>>       end loop;
>>>>
>>>> I am not comfortable with the semantics of this and with possible
>>>> implications too. I would keep it simple.
>>>
>>> Interesting. Can you pin down some of that discomfort? It looks simple
>>> to me :
>>>
>>> "indefinite" indicates the size can vary (and the compiler knows
>>> whether it used the heap or stack), and in the absence of "aliased" we
>>> know there are no copies of the pointer (if heap).
>>
>> I don't like compiler relocating objects. If the pool is a stack (or
>> heap organized as a stack) it might be unable to do this.
> 
> Ah OK, I see it.
> 
> The compiler should be able to determine if (as in the loop above) the
> use of Q (the indefinite type) is equivalent to a Declare block (i.e. can
> be on the stack; new stack frame in each iteration; no relocation ever
> required) or not.

I don't want the compiler deciding where Q is allocated, especially 
because this could break things:

1. Large object moved to the stack

2. Lock-free code starting using heap lock when moved from the stack.

The mechanism should be transparent. I do not like Unbounded_String for 
many reasons. Fiddling with the heap is one of them. I do not know which 
heuristic it uses to reduce reallocation and how much extra memory it 
takes under which circumstances.

>> In general, there are two close but not equivalent objectives one is
>> handling indefinite components of records another is a transparent
>> holder object integrated into the language (without generic mess).
>>
>> Your use case is about the latter. My is rather the former.
> 
> If a record with even one indefinite component is an indefinite record,
> and therefore embedded in a transparent holder (I like that term), aren't
> they equivalent?

I don't understand this question.

>>> Honest question : Inconsistent with what?
>>> I suggested shallow copy just for simplicity, and for no (ahh) deeper
>>> reason. But again, I'm probably missing something.
>>
>> If you make a shallow copy of
>>
>>      type Node_Type is record
>>         Item : new Element_Type;
>>         Prev : Node_Ptr_Type; Next : Node_Ptr_Type;
>>      end record;
>>
>> you create a dangling pointer should the original node disappear. A deep
>> copy would create a new target for new Item.
> 
> You are using "new" to signify Item is indefinite, I think?
> 
> But the problem is that Prev,Next are copies of the original Prev,Next
> pointers, so if the original Node_Type is then freed, they are dangling?

They are supposed to be handled by the doubly-linked list 
infrastructure, e.g. Prev and Next pointing to the node itself is a 
precondition for freeing the node.

The problem is with the node contents.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-04-03 22:48 Proposal: Auto-allocation of Indefinite Objects Stephen Davies
                   ` (2 preceding siblings ...)
  2020-07-27  7:47 ` Yannick Moy
@ 2020-07-31  9:25 ` Stephen Davies
  2020-07-31 10:20   ` Dmitry A. Kazakov
  2020-09-03  4:30 ` linda white
  4 siblings, 1 reply; 47+ messages in thread
From: Stephen Davies @ 2020-07-31  9:25 UTC (permalink / raw)


On Friday, 3 April 2020 at 23:48:43 UTC+1, Stephen Davies wrote:
> type Node_Type is record 
> Item : new Element_Type; 
> Prev : Node_Ptr_Type; 
> Next : Node_Ptr_Type; 
> end record; 

Perhaps a better way to think of this is as a discriminated record without
an explicit discriminant? In which case maybe a different syntax than "new"
would be appropriate?

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-31  9:25 ` Stephen Davies
@ 2020-07-31 10:20   ` Dmitry A. Kazakov
  2020-08-01 11:22     ` Stephen Davies
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-07-31 10:20 UTC (permalink / raw)


On 31/07/2020 11:25, Stephen Davies wrote:
> On Friday, 3 April 2020 at 23:48:43 UTC+1, Stephen Davies wrote:
>> type Node_Type is record
>> Item : new Element_Type;
>> Prev : Node_Ptr_Type;
>> Next : Node_Ptr_Type;
>> end record;
> 
> Perhaps a better way to think of this is as a discriminated record without
> an explicit discriminant? In which case maybe a different syntax than "new"
> would be appropriate?

That is right, but it would be a much larger problem to resolve than 
your original proposal.

First, Ada lacks necessary discriminants, e.g.

   type Node_Type (Descendant : Ada.Tags.Tag) is record
      Item : Element_Type (Tag => Descendant);
      Prev : Node_Ptr_Type;
      Next : Node_Ptr_Type;
   end record;

Here Element_Type is a specific type from Element_Type'Class which tag 
is Descendant.

Second, Ada's object initialization process has no means to determine 
discriminants. One extra step is missing before a call to allocator to 
provide constraints of a type. [I proposed a record type T'Constraints 
that would contain all constraints and no data to be passed to allocator 
to determine the object constraints and thus its size.]

Third, there is still the problem that task components do not work, as 
well as all other cases when the Rosen trick is used to work-around full 
multiple inheritance by making record members out of intended parents.

All in one, the crude work-around has always been an access type, which 
your original proposal would handle with much more grace.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-31 10:20   ` Dmitry A. Kazakov
@ 2020-08-01 11:22     ` Stephen Davies
  2020-08-01 12:58       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Stephen Davies @ 2020-08-01 11:22 UTC (permalink / raw)


On Friday, 31 July 2020 at 11:20:09 UTC+1, Dmitry A. Kazakov wrote:
> On 31/07/2020 11:25, Stephen Davies wrote: 
> > On Friday, 3 April 2020 at 23:48:43 UTC+1, Stephen Davies wrote: 
> > Perhaps a better way to think of this is as a discriminated record without 
> > an explicit discriminant? In which case maybe a different syntax than "new" 
> > would be appropriate?
> That is right, but it would be a much larger problem to resolve than 
> your original proposal. 
> First, Ada lacks necessary discriminants ... 
> Second, Ada's object initialization process has no means to determine 
> discriminants...
> Third, there is still the problem that task components do not work...
> All in one, the crude work-around has always been an access type...

Maybe I'm missing something but my thought was maybe there is no
need for a named discriminant, e.g.
type Node_Type (<>) is record
   Item : Element_Type;
   Prev : Node_Ptr_Type;
   Next : Node_Ptr_Type;
end record;
The rules for such records would be the same as for discriminated ones,
except that instead of usages needing to provide values for discriminants,
they would need to provide values for indefinite components.

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-01 11:22     ` Stephen Davies
@ 2020-08-01 12:58       ` Dmitry A. Kazakov
  2020-08-01 20:35         ` Stephen Davies
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-01 12:58 UTC (permalink / raw)


On 01/08/2020 13:22, Stephen Davies wrote:
> On Friday, 31 July 2020 at 11:20:09 UTC+1, Dmitry A. Kazakov wrote:
>> On 31/07/2020 11:25, Stephen Davies wrote:
>>> On Friday, 3 April 2020 at 23:48:43 UTC+1, Stephen Davies wrote:
>>> Perhaps a better way to think of this is as a discriminated record without
>>> an explicit discriminant? In which case maybe a different syntax than "new"
>>> would be appropriate?
>> That is right, but it would be a much larger problem to resolve than
>> your original proposal.
>> First, Ada lacks necessary discriminants ...
>> Second, Ada's object initialization process has no means to determine
>> discriminants...
>> Third, there is still the problem that task components do not work...
>> All in one, the crude work-around has always been an access type...
> 
> Maybe I'm missing something but my thought was maybe there is no
> need for a named discriminant, e.g.
> type Node_Type (<>) is record
>     Item : Element_Type;
>     Prev : Node_Ptr_Type;
>     Next : Node_Ptr_Type;
> end record;
> The rules for such records would be the same as for discriminated ones,
> except that instead of usages needing to provide values for discriminants,
> they would need to provide values for indefinite components.

1. There is no discriminants for cases when Item is T'Class.

2. You cannot get discriminant from the value in the case of Rosen 
trick. Consider Item being a task with the access to the actual node as 
its discriminant:

    type Node_Type;
    task type Worker (Node : not null access Node_Type) is ...;
    type Mode_Type is record
       Item : Worker (Node_Type'Unchecked_Access);
       Prev : Node_Ptr_Type;
       Next : Node_Ptr_Type;
    end record;

You cannot initialize Item because you cannot construct Worker without 
having the node. And you cannot have the node without having Item 
initialized.

3. Copying is involved. There should be none, especially for limited 
types. Limited returns are broken per construction and nothing could 
ever fix them.

-------------------------
If the only problem were to deduce discriminants from a value. We could 
leave Node_Type as-is and simply fix aggregates:

    type T (L : Natural) is record
       S : String (1..L);
       I : Integer;
    end record;

Why not to make this legal?

    X : T := ("hello!", 123); -- L is deduced from S

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-01 12:58       ` Dmitry A. Kazakov
@ 2020-08-01 20:35         ` Stephen Davies
  2020-08-01 20:56           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Stephen Davies @ 2020-08-01 20:35 UTC (permalink / raw)


On Saturday, 1 August 2020 at 13:58:10 UTC+1, Dmitry A. Kazakov wrote:
> On 01/08/2020 13:22, Stephen Davies wrote: 
> > type Node_Type (<>) is record 
> > Item : Element_Type; 
> > Prev : Node_Ptr_Type; 
> > Next : Node_Ptr_Type; 
> > end record; 
> > The rules for such records would be the same as for discriminated ones, 
> > except that instead of usages needing to provide values for discriminants, 
> > they would need to provide values for indefinite components.
> 1. There is no discriminants for cases when Item is T'Class. 
> 2. You cannot get discriminant from the value in the case of Rosen trick...
> 3. Copying is involved. There should be none, especially for limited types...
I'm mainly talking about situations in which there doesn't need to be a
discriminant at all, e.g. when Element_Type is an indefinite non-limited
generic parameter. In other words, Node_Type would then also be indefinite,
but not discriminated.
> Why not to make this legal?
> X : T := ("hello!", 123); -- L is deduced from S
Maybe that's something that should be fixed anyway, though this is indeed
another situation that (both versions of) my proposal would address, by
removing (the somewhat redundant) L altogether.

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-01 20:35         ` Stephen Davies
@ 2020-08-01 20:56           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-01 20:56 UTC (permalink / raw)


On 01/08/2020 22:35, Stephen Davies wrote:
> On Saturday, 1 August 2020 at 13:58:10 UTC+1, Dmitry A. Kazakov wrote:
>> On 01/08/2020 13:22, Stephen Davies wrote:
>>> type Node_Type (<>) is record
>>> Item : Element_Type;
>>> Prev : Node_Ptr_Type;
>>> Next : Node_Ptr_Type;
>>> end record;
>>> The rules for such records would be the same as for discriminated ones,
>>> except that instead of usages needing to provide values for discriminants,
>>> they would need to provide values for indefinite components.
>> 1. There is no discriminants for cases when Item is T'Class.
>> 2. You cannot get discriminant from the value in the case of Rosen trick...
>> 3. Copying is involved. There should be none, especially for limited types...
> I'm mainly talking about situations in which there doesn't need to be a
> discriminant at all, e.g. when Element_Type is an indefinite non-limited
> generic parameter. In other words, Node_Type would then also be indefinite,
> but not discriminated.

In my view all indefinite types are discriminated, though some 
discriminants are anonymous or represented by attributes, per language 
design irregularities. E.g. T'Class is discriminated by the type tag. 
Array bounds must clearly be discriminants etc. Each constraint must be 
expressed in terms of discriminants.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-29 16:20             ` Dmitry A. Kazakov
  2020-07-30 13:37               ` Stephen Davies
  2020-07-30 17:04               ` Brian Drummond
@ 2020-08-10  0:31               ` Randy Brukardt
  2020-08-10  8:58                 ` Dmitry A. Kazakov
  2 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-10  0:31 UTC (permalink / raw)


"Dmitry A. Kazakov" <[email protected]> wrote in message 
news:[email protected]
> On 29/07/2020 17:33, Brian Drummond wrote:
>> On Tue, 28 Jul 2020 16:59:09 +0200, Dmitry A. Kazakov wrote:
>
>>>>      A constant String := "done";
>>>>      Q : indefinite String;
>>>>    ...
>>>>      loop
>>>>         Q := Get_Line;
>>>>         exit when Q = A;
>>>>      end loop;
>>>
>>> I am not comfortable with the semantics of this and with possible
>>> implications too. I would keep it simple.
>>
>> Interesting. Can you pin down some of that discomfort? It looks simple to
>> me :
>>
>> "indefinite" indicates the size can vary (and the compiler knows whether
>> it used the heap or stack), and in the absence of "aliased" we know there
>> are no copies of the pointer (if heap).
>
> I don't like compiler relocating objects. If the pool is a stack (or heap 
> organized as a stack) it might be unable to do this.

This is not that hard to deal with. Janus/Ada handles discriminant-dependent 
components of mutable objects this way: they are allocated on the stack, but 
if they have to be reallocated they move to the heap.

I note that the original idea already exists for discriminant-dependent 
components -- that's a bit more painful to use but hardly difficult. The 
main issue is that most compilers fail to support these components properly, 
using some sort of max-size implementation unconditionally rather than 
switching to a pool-based implementation when the max size is too large. 
I've never understood why Ada compilers were allowed to make such a 
limitation (it becomes a major limitation when working on non-embedded 
programs), while similar limitations on case statements and aggregates are 
not allowed.

                                         Randy.


 


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-07-30 18:28                 ` Dmitry A. Kazakov
@ 2020-08-10  0:39                   ` Randy Brukardt
  2020-08-10  8:57                     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-10  0:39 UTC (permalink / raw)


"Dmitry A. Kazakov" <[email protected]> wrote in message 
news:[email protected]
> On 30/07/2020 19:04, Brian Drummond wrote:
>> On Wed, 29 Jul 2020 18:20:24 +0200, Dmitry A. Kazakov wrote:
>>
>>> On 29/07/2020 17:33, Brian Drummond wrote:
>>>> On Tue, 28 Jul 2020 16:59:09 +0200, Dmitry A. Kazakov wrote:
>>>
>>>>>>       A constant String := "done";
>>>>>>       Q : indefinite String;
>>>>>>     ...
>>>>>>       loop
>>>>>>          Q := Get_Line; exit when Q = A;
>>>>>>       end loop;
>>>>>
>>>>> I am not comfortable with the semantics of this and with possible
>>>>> implications too. I would keep it simple.
>>>>
>>>> Interesting. Can you pin down some of that discomfort? It looks simple
>>>> to me :
>>>>
>>>> "indefinite" indicates the size can vary (and the compiler knows
>>>> whether it used the heap or stack), and in the absence of "aliased" we
>>>> know there are no copies of the pointer (if heap).
>>>
>>> I don't like compiler relocating objects. If the pool is a stack (or
>>> heap organized as a stack) it might be unable to do this.
>>
>> Ah OK, I see it.
>>
>> The compiler should be able to determine if (as in the loop above) the
>> use of Q (the indefinite type) is equivalent to a Declare block (i.e. can
>> be on the stack; new stack frame in each iteration; no relocation ever
>> required) or not.
>
> I don't want the compiler deciding where Q is allocated, especially 
> because this could break things:
>
> 1. Large object moved to the stack

The compiler is buggy IMHO if this breaks something. Any compiler has to be 
able to deal with objects that exceed the maximum stack frame, and move 
those to somewhere that they will fit (or reject completely).

Yes, most compilers are buggy this way (including mine in a few cases). So 
what?

> 2. Lock-free code starting using heap lock when moved from the stack.

Expecting a compiler not to use the heap is silly in any case (outside of 
the No_Heap restriction - use that in Janus/Ada and the compiler refuses to 
do anything outside of elementary types). The compiler is supposed to be 
making the programmer's life easier, not adding new hurdles.

> The mechanism should be transparent. I do not like Unbounded_String for 
> many reasons. Fiddling with the heap is one of them. I do not know which 
> heuristic it uses to reduce reallocation and how much extra memory it 
> takes under which circumstances.

That's the idea of such mechanisms. If you really need control, you do not 
use these abstractions and instead write the stuff yourself explicitly using 
access types and the like.

Otherwise, you use containers and unbounded strings, and they do what they 
do. There's no free lunch. But the need to be explicit should be very rare - 
the main problem is programmers with insufficient trust that a compiler will 
do the right thing.

                              Randy.


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-10  0:39                   ` Randy Brukardt
@ 2020-08-10  8:57                     ` Dmitry A. Kazakov
  2020-08-20  0:10                       ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-10  8:57 UTC (permalink / raw)


On 10/08/2020 02:39, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <[email protected]> wrote in message
> news:[email protected]

>> I don't want the compiler deciding where Q is allocated, especially
>> because this could break things:
>>
>> 1. Large object moved to the stack
> 
> The compiler is buggy IMHO if this breaks something. Any compiler has to be
> able to deal with objects that exceed the maximum stack frame, and move
> those to somewhere that they will fit (or reject completely).
> 
> Yes, most compilers are buggy this way (including mine in a few cases). So
> what?
> 
>> 2. Lock-free code starting using heap lock when moved from the stack.
> 
> Expecting a compiler not to use the heap is silly in any case (outside of
> the No_Heap restriction - use that in Janus/Ada and the compiler refuses to
> do anything outside of elementary types). The compiler is supposed to be
> making the programmer's life easier, not adding new hurdles.
> 
>> The mechanism should be transparent. I do not like Unbounded_String for
>> many reasons. Fiddling with the heap is one of them. I do not know which
>> heuristic it uses to reduce reallocation and how much extra memory it
>> takes under which circumstances.
> 
> That's the idea of such mechanisms. If you really need control, you do not
> use these abstractions and instead write the stuff yourself explicitly using
> access types and the like.

Right, that is my take on the proposal. If I am ready to compromise on 
#1 and #2, I can use an abstraction hiding pool access. Otherwise I want 
a language construct being more safe than raw access types.

> Otherwise, you use containers and unbounded strings, and they do what they
> do.

No, from the abstraction point of view they do not. They indeed abstract 
the memory allocation aspect, but they do that at the cost of 
*everything* else. Unbounded_String is no string anymore. Container is 
neither array nor record type. Unbounded_String must be converted forth 
and back. For containers I must use ugly hacks like iterators to make 
them resemble arrays and records introducing whole levels of complexity 
to fight through every time the compiler or I miss something.

In most cases I prefer to keep a clear array or record interface at the 
expense of manual memory management.

> There's no free lunch.

I think with a better type system there could be a whole banquet. (:-))

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-10  0:31               ` Randy Brukardt
@ 2020-08-10  8:58                 ` Dmitry A. Kazakov
  2020-08-20  0:13                   ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-10  8:58 UTC (permalink / raw)


On 10/08/2020 02:31, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <[email protected]> wrote in message
> news:[email protected]
>> On 29/07/2020 17:33, Brian Drummond wrote:
>>> On Tue, 28 Jul 2020 16:59:09 +0200, Dmitry A. Kazakov wrote:
>>
>>>>>       A constant String := "done";
>>>>>       Q : indefinite String;
>>>>>     ...
>>>>>       loop
>>>>>          Q := Get_Line;
>>>>>          exit when Q = A;
>>>>>       end loop;
>>>>
>>>> I am not comfortable with the semantics of this and with possible
>>>> implications too. I would keep it simple.
>>>
>>> Interesting. Can you pin down some of that discomfort? It looks simple to
>>> me :
>>>
>>> "indefinite" indicates the size can vary (and the compiler knows whether
>>> it used the heap or stack), and in the absence of "aliased" we know there
>>> are no copies of the pointer (if heap).
>>
>> I don't like compiler relocating objects. If the pool is a stack (or heap
>> organized as a stack) it might be unable to do this.
> 
> This is not that hard to deal with. Janus/Ada handles discriminant-dependent
> components of mutable objects this way: they are allocated on the stack, but
> if they have to be reallocated they move to the heap.

What you do if such an object is allocated via pool-specific access type?

> I note that the original idea already exists for discriminant-dependent
> components -- that's a bit more painful to use but hardly difficult. The
> main issue is that most compilers fail to support these components properly,
> using some sort of max-size implementation unconditionally rather than
> switching to a pool-based implementation when the max size is too large.
> I've never understood why Ada compilers were allowed to make such a
> limitation (it becomes a major limitation when working on non-embedded
> programs), while similar limitations on case statements and aggregates are
> not allowed.

I think a non-embedded target could use a task-local pool for the purpose.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-10  8:57                     ` Dmitry A. Kazakov
@ 2020-08-20  0:10                       ` Randy Brukardt
  2020-08-20 17:49                         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-20  0:10 UTC (permalink / raw)


"Dmitry A. Kazakov" <[email protected]> wrote in message 
news:[email protected]
> No, from the abstraction point of view they do not. They indeed abstract 
> the memory allocation aspect, but they do that at the cost of *everything* 
> else. Unbounded_String is no string anymore. Container is neither array 
> nor record type. Unbounded_String must be converted forth and back. For 
> containers I must use ugly hacks like iterators to make them resemble 
> arrays and records introducing whole levels of complexity to fight through 
> every time the compiler or I miss something.
>
> In most cases I prefer to keep a clear array or record interface at the 
> expense of manual memory management.
>
>> There's no free lunch.
>
> I think with a better type system there could be a whole banquet. (:-))

Maybe. but IMHO a better type system would get rid of arrays and strings 
altogether and only have containers/records of various sorts. The complexity 
of having both solving the same problems (not very well in the case of 
arrays/strings) doesn't buy much. I suspect that a user-defined "." as 
you've proposed elsewhere would eliminate most of the rest of the problems 
(and unify everything even further).

                                  Randy.


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-10  8:58                 ` Dmitry A. Kazakov
@ 2020-08-20  0:13                   ` Randy Brukardt
  2020-08-20 17:49                     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-20  0:13 UTC (permalink / raw)


"Dmitry A. Kazakov" <[email protected]> wrote in message 
news:[email protected]
> On 10/08/2020 02:31, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <[email protected]> wrote in message
>> news:[email protected]
>>> On 29/07/2020 17:33, Brian Drummond wrote:
>>>> On Tue, 28 Jul 2020 16:59:09 +0200, Dmitry A. Kazakov wrote:
>>>
>>>>>>       A constant String := "done";
>>>>>>       Q : indefinite String;
>>>>>>     ...
>>>>>>       loop
>>>>>>          Q := Get_Line;
>>>>>>          exit when Q = A;
>>>>>>       end loop;
>>>>>
>>>>> I am not comfortable with the semantics of this and with possible
>>>>> implications too. I would keep it simple.
>>>>
>>>> Interesting. Can you pin down some of that discomfort? It looks simple 
>>>> to
>>>> me :
>>>>
>>>> "indefinite" indicates the size can vary (and the compiler knows 
>>>> whether
>>>> it used the heap or stack), and in the absence of "aliased" we know 
>>>> there
>>>> are no copies of the pointer (if heap).
>>>
>>> I don't like compiler relocating objects. If the pool is a stack (or 
>>> heap
>>> organized as a stack) it might be unable to do this.
>>
>> This is not that hard to deal with. Janus/Ada handles 
>> discriminant-dependent
>> components of mutable objects this way: they are allocated on the stack, 
>> but
>> if they have to be reallocated they move to the heap.
>
> What you do if such an object is allocated via pool-specific access type?

The whole object goes in that pool. The entire mechanism in Janus/Ada is 
built around pools - the stack is represented by a pool object as well as 
various other pools to support the mechanism.

>> I note that the original idea already exists for discriminant-dependent
>> components -- that's a bit more painful to use but hardly difficult. The
>> main issue is that most compilers fail to support these components 
>> properly,
>> using some sort of max-size implementation unconditionally rather than
>> switching to a pool-based implementation when the max size is too large.
>> I've never understood why Ada compilers were allowed to make such a
>> limitation (it becomes a major limitation when working on non-embedded
>> programs), while similar limitations on case statements and aggregates 
>> are
>> not allowed.
>
> I think a non-embedded target could use a task-local pool for the purpose.

At the cost of using explicit allocators and effectively leaking memory 
(most tasks are fairly long-lived, much longer than the majority of 
objects).

                        Randy.


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-20  0:13                   ` Randy Brukardt
@ 2020-08-20 17:49                     ` Dmitry A. Kazakov
  2020-08-20 23:25                       ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-20 17:49 UTC (permalink / raw)


On 20/08/2020 02:13, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <[email protected]> wrote in message
> news:[email protected]
>> On 10/08/2020 02:31, Randy Brukardt wrote:

>>> This is not that hard to deal with. Janus/Ada handles
>>> discriminant-dependent
>>> components of mutable objects this way: they are allocated on the stack,
>>> but
>>> if they have to be reallocated they move to the heap.
>>
>> What you do if such an object is allocated via pool-specific access type?
> 
> The whole object goes in that pool. The entire mechanism in Janus/Ada is
> built around pools - the stack is represented by a pool object as well as
> various other pools to support the mechanism.

OK, but then you are back to the problem that you do not know how that 
pool works. The user pool might require a certain order of objects 
inside it and your interference with relocation will break it.

>>> I note that the original idea already exists for discriminant-dependent
>>> components -- that's a bit more painful to use but hardly difficult. The
>>> main issue is that most compilers fail to support these components
>>> properly,
>>> using some sort of max-size implementation unconditionally rather than
>>> switching to a pool-based implementation when the max size is too large.
>>> I've never understood why Ada compilers were allowed to make such a
>>> limitation (it becomes a major limitation when working on non-embedded
>>> programs), while similar limitations on case statements and aggregates
>>> are
>>> not allowed.
>>
>> I think a non-embedded target could use a task-local pool for the purpose.
> 
> At the cost of using explicit allocators and effectively leaking memory
> (most tasks are fairly long-lived, much longer than the majority of
> objects).

No, I meant that if you used a pool behind the scenes for local objects 
you could do that task-specific eliminating interlocking.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-20  0:10                       ` Randy Brukardt
@ 2020-08-20 17:49                         ` Dmitry A. Kazakov
  2020-08-20 20:19                           ` Dennis Lee Bieber
  2020-08-20 23:30                           ` Randy Brukardt
  0 siblings, 2 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-20 17:49 UTC (permalink / raw)


On 20/08/2020 02:10, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <[email protected]> wrote in message
> news:[email protected]
>> No, from the abstraction point of view they do not. They indeed abstract
>> the memory allocation aspect, but they do that at the cost of *everything*
>> else. Unbounded_String is no string anymore. Container is neither array
>> nor record type. Unbounded_String must be converted forth and back. For
>> containers I must use ugly hacks like iterators to make them resemble
>> arrays and records introducing whole levels of complexity to fight through
>> every time the compiler or I miss something.
>>
>> In most cases I prefer to keep a clear array or record interface at the
>> expense of manual memory management.
>>
>>> There's no free lunch.
>>
>> I think with a better type system there could be a whole banquet. (:-))
> 
> Maybe. but IMHO a better type system would get rid of arrays and strings
> altogether and only have containers/records of various sorts. The complexity
> of having both solving the same problems (not very well in the case of
> arrays/strings) doesn't buy much. I suspect that a user-defined "." as
> you've proposed elsewhere would eliminate most of the rest of the problems
> (and unify everything even further).

But records and arrays are needed as building blocks of containers. How 
would you get rid of them?

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-20 17:49                         ` Dmitry A. Kazakov
@ 2020-08-20 20:19                           ` Dennis Lee Bieber
  2020-08-20 23:33                             ` Randy Brukardt
  2020-08-20 23:30                           ` Randy Brukardt
  1 sibling, 1 reply; 47+ messages in thread
From: Dennis Lee Bieber @ 2020-08-20 20:19 UTC (permalink / raw)


On Thu, 20 Aug 2020 19:49:44 +0200, "Dmitry A. Kazakov"
<[email protected]> declaimed the following:

>
>But records and arrays are needed as building blocks of containers. How 
>would you get rid of them?

	And likely needed for any embedded or low-level work where they are
mapped to things like (GP) I/O ports or such...


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	[email protected]    http://wlfraed.microdiversity.freeddns.org/

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-20 17:49                     ` Dmitry A. Kazakov
@ 2020-08-20 23:25                       ` Randy Brukardt
  2020-08-21  7:08                         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-20 23:25 UTC (permalink / raw)


"Dmitry A. Kazakov" <[email protected]> wrote in message 
news:[email protected]
> On 20/08/2020 02:13, Randy Brukardt wrote:
...
>>> What you do if such an object is allocated via pool-specific access 
>>> type?
>>
>> The whole object goes in that pool. The entire mechanism in Janus/Ada is
>> built around pools - the stack is represented by a pool object as well as
>> various other pools to support the mechanism.
>
> OK, but then you are back to the problem that you do not know how that 
> pool works. The user pool might require a certain order of objects inside 
> it and your interference with relocation will break it.

Such a pool does not implement the interface as defined in 13.11. It's OK of 
course to write a pool that depends on implementation-specific properties 
(I've done it many times), but such a pool is not usable with portable Ada 
code. If the pool allows any sort of allocation at any time, then it will 
work just fine with the Janus/Ada implementation.

(Of course, you can use a one-size only pool allocation with Janus/Ada, so 
long as what you are allocating doesn't have discrimiant-dependent 
components. Janus/Ada has informational messages about such components, so 
you can do it if you want/need. Probably should have an aspect as well to 
force an error if a static size is expected.)

Note that this is the reason that Ada doesn't support specifying the pool 
used by a container. It would not be reasonable to restrict the allocations 
in any way, so implementation-dependent pool designs would not work.

>>>> I note that the original idea already exists for discriminant-dependent
>>>> components -- that's a bit more painful to use but hardly difficult. 
>>>> The
>>>> main issue is that most compilers fail to support these components 
>>>> properly,
>>>> using some sort of max-size implementation unconditionally rather than
>>>> switching to a pool-based implementation when the max size is too 
>>>> large.
>>>> I've never understood why Ada compilers were allowed to make such a
>>>> limitation (it becomes a major limitation when working on non-embedded
>>>> programs), while similar limitations on case statements and aggregates
>>>> are not allowed.
>>>
>>> I think a non-embedded target could use a task-local pool for the 
>>> purpose.
>>
>> At the cost of using explicit allocators and effectively leaking memory
>> (most tasks are fairly long-lived, much longer than the majority of
>> objects).
>
> No, I meant that if you used a pool behind the scenes for local objects 
> you could do that task-specific eliminating interlocking.

Whether that would be worthwhile would depend on how expensive the locking 
is. If a lock-free algorithm was used, it might be cheap enough to not make 
it worth bothering (the actual heap manipulation usually being more 
expensive given the free chain searching). [A lock-free algorithm typically 
using busy-waiting rather than suspension to wait.]

Of course, Janus/Ada itself uses the Windows heap for heap management, so 
the locking is already built-in and not paying for it is not an option. But 
roll-your-own-heap managers (as Janus/Ada used on CP/M and MS-DOS) have 
options.

                                Randy.



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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-20 17:49                         ` Dmitry A. Kazakov
  2020-08-20 20:19                           ` Dennis Lee Bieber
@ 2020-08-20 23:30                           ` Randy Brukardt
  2020-08-21  6:46                             ` Dmitry A. Kazakov
  1 sibling, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-20 23:30 UTC (permalink / raw)


"Dmitry A. Kazakov" <[email protected]> wrote in message 
news:[email protected]
> On 20/08/2020 02:10, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <[email protected]> wrote in message
>> news:[email protected]
>>> No, from the abstraction point of view they do not. They indeed abstract
>>> the memory allocation aspect, but they do that at the cost of 
>>> *everything*
>>> else. Unbounded_String is no string anymore. Container is neither array
>>> nor record type. Unbounded_String must be converted forth and back. For
>>> containers I must use ugly hacks like iterators to make them resemble
>>> arrays and records introducing whole levels of complexity to fight 
>>> through
>>> every time the compiler or I miss something.
>>>
>>> In most cases I prefer to keep a clear array or record interface at the
>>> expense of manual memory management.
>>>
>>>> There's no free lunch.
>>>
>>> I think with a better type system there could be a whole banquet. (:-))
>>
>> Maybe. but IMHO a better type system would get rid of arrays and strings
>> altogether and only have containers/records of various sorts. The 
>> complexity
>> of having both solving the same problems (not very well in the case of
>> arrays/strings) doesn't buy much. I suspect that a user-defined "." as
>> you've proposed elsewhere would eliminate most of the rest of the 
>> problems
>> (and unify everything even further).
>
> But records and arrays are needed as building blocks of containers. How 
> would you get rid of them?

There's no reason that a compiler couldn't "build-in" a simple bounded 
vector container as the basic building block. We already do that for things 
like Ada.Exceptions, Unchecked_Conversion, and Unchecked_Deallocation, so 
it's no harder to do that for a vector. (Probably would need some sort of 
fixed vector for interfacing purposes as well, to deal with other language's 
and/or system's memory layout.)

One could do something similar for records, although I would probably leave 
them as in Ada and just allow user-definition of "." (via a getter/setter 
pair).

                                 Randy.


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-20 20:19                           ` Dennis Lee Bieber
@ 2020-08-20 23:33                             ` Randy Brukardt
  2020-08-21  6:45                               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-20 23:33 UTC (permalink / raw)


"Dennis Lee Bieber" <[email protected]> wrote in message 
news:[email protected]
> On Thu, 20 Aug 2020 19:49:44 +0200, "Dmitry A. Kazakov"
> <[email protected]> declaimed the following:
>
>>
>>But records and arrays are needed as building blocks of containers. How
>>would you get rid of them?
>
> And likely needed for any embedded or low-level work where they are
> mapped to things like (GP) I/O ports or such...

Yes, a fixed vector container would be needed for interfacing (probably 
wouldn't use it for anything else). But there's no reason that can't be 
provided as a container, so long as representation guarentees (esp. 
Component_Size) are included. Remember that containers (in Ada 202x) have 
indexing, aggregates, and all of the useful basic operations. The stuff 
that's missing is the same stuff that adds a vast amount of complexity to 
Ada (and possibilities for bugs) - hardly anyone would miss it.

                                    Randy.


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-20 23:33                             ` Randy Brukardt
@ 2020-08-21  6:45                               ` Dmitry A. Kazakov
  2020-08-23  4:52                                 ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-21  6:45 UTC (permalink / raw)


On 21/08/2020 01:33, Randy Brukardt wrote:
> "Dennis Lee Bieber" <[email protected]> wrote in message
> news:[email protected]
>> On Thu, 20 Aug 2020 19:49:44 +0200, "Dmitry A. Kazakov"
>> <[email protected]> declaimed the following:
>>
>>>
>>> But records and arrays are needed as building blocks of containers. How
>>> would you get rid of them?
>>
>> And likely needed for any embedded or low-level work where they are
>> mapped to things like (GP) I/O ports or such...
> 
> Yes, a fixed vector container would be needed for interfacing (probably
> wouldn't use it for anything else). But there's no reason that can't be
> provided as a container, so long as representation guarentees (esp.
> Component_Size) are included. Remember that containers (in Ada 202x) have
> indexing, aggregates, and all of the useful basic operations. The stuff
> that's missing is the same stuff that adds a vast amount of complexity to
> Ada (and possibilities for bugs) - hardly anyone would miss it.

Really? I would miss array conversions, slices, equivalence of same 
length index ranges, constrained array subtypes etc.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-20 23:30                           ` Randy Brukardt
@ 2020-08-21  6:46                             ` Dmitry A. Kazakov
  2020-08-23  4:48                               ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-21  6:46 UTC (permalink / raw)


On 21/08/2020 01:30, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <[email protected]> wrote in message
> news:[email protected]
>> On 20/08/2020 02:10, Randy Brukardt wrote:
>>> "Dmitry A. Kazakov" <[email protected]> wrote in message
>>> news:[email protected]
>>>> No, from the abstraction point of view they do not. They indeed abstract
>>>> the memory allocation aspect, but they do that at the cost of
>>>> *everything*
>>>> else. Unbounded_String is no string anymore. Container is neither array
>>>> nor record type. Unbounded_String must be converted forth and back. For
>>>> containers I must use ugly hacks like iterators to make them resemble
>>>> arrays and records introducing whole levels of complexity to fight
>>>> through
>>>> every time the compiler or I miss something.
>>>>
>>>> In most cases I prefer to keep a clear array or record interface at the
>>>> expense of manual memory management.
>>>>
>>>>> There's no free lunch.
>>>>
>>>> I think with a better type system there could be a whole banquet. (:-))
>>>
>>> Maybe. but IMHO a better type system would get rid of arrays and strings
>>> altogether and only have containers/records of various sorts. The
>>> complexity
>>> of having both solving the same problems (not very well in the case of
>>> arrays/strings) doesn't buy much. I suspect that a user-defined "." as
>>> you've proposed elsewhere would eliminate most of the rest of the
>>> problems
>>> (and unify everything even further).
>>
>> But records and arrays are needed as building blocks of containers. How
>> would you get rid of them?
> 
> There's no reason that a compiler couldn't "build-in" a simple bounded
> vector container as the basic building block.

That simply replaces the word "array" with four words "simple bounded 
vector container." The construct is still there and it is still 
built-in. The syntax and usability are drastically worse, though.

> One could do something similar for records, although I would probably leave
> them as in Ada and just allow user-definition of "." (via a getter/setter
> pair).

Ditto.

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-20 23:25                       ` Randy Brukardt
@ 2020-08-21  7:08                         ` Dmitry A. Kazakov
  2020-08-23  5:03                           ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-21  7:08 UTC (permalink / raw)


On 21/08/2020 01:25, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <[email protected]> wrote in message
> news:[email protected]
>> On 20/08/2020 02:13, Randy Brukardt wrote:
> ...
>>>> What you do if such an object is allocated via pool-specific access
>>>> type?
>>>
>>> The whole object goes in that pool. The entire mechanism in Janus/Ada is
>>> built around pools - the stack is represented by a pool object as well as
>>> various other pools to support the mechanism.
>>
>> OK, but then you are back to the problem that you do not know how that
>> pool works. The user pool might require a certain order of objects inside
>> it and your interference with relocation will break it.
> 
> Such a pool does not implement the interface as defined in 13.11. It's OK of
> course to write a pool that depends on implementation-specific properties
> (I've done it many times), but such a pool is not usable with portable Ada
> code. If the pool allows any sort of allocation at any time, then it will
> work just fine with the Janus/Ada implementation.

It is a different situation. Such pools are not intended as a general 
purpose pools. But the type is. In my view an implementation of the type 
provided by compiler must work in all legal cases. Otherwise it is 
either language of compiler bug.

> (Of course, you can use a one-size only pool allocation with Janus/Ada, so
> long as what you are allocating doesn't have discrimiant-dependent
> components. Janus/Ada has informational messages about such components, so
> you can do it if you want/need. Probably should have an aspect as well to
> force an error if a static size is expected.)
> 
> Note that this is the reason that Ada doesn't support specifying the pool
> used by a container. It would not be reasonable to restrict the allocations
> in any way, so implementation-dependent pool designs would not work.
> 
>> No, I meant that if you used a pool behind the scenes for local objects
>> you could do that task-specific eliminating interlocking.
> 
> Whether that would be worthwhile would depend on how expensive the locking
> is.

It could be very expensive on a multi-core architecture. I also think 
about scenarios when the object is used inside a protected action. I 
would not like to see any pool interaction in an interrupt handler!

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-21  6:46                             ` Dmitry A. Kazakov
@ 2020-08-23  4:48                               ` Randy Brukardt
  2020-08-23 12:29                                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-23  4:48 UTC (permalink / raw)


"Dmitry A. Kazakov" <[email protected]> wrote in message 
news:[email protected]
> On 21/08/2020 01:30, Randy Brukardt wrote:
...
>> There's no reason that a compiler couldn't "build-in" a simple bounded
>> vector container as the basic building block.
>
> That simply replaces the word "array" with four words "simple bounded 
> vector container." The construct is still there and it is still built-in. 
> The syntax and usability are drastically worse, though.

??? The syntax of use is the same (as it is in Ada 2012). Declaration would 
be an instance, about the same length and wordiness as an array declaration. 
Yes, junk like slices, settable/retrievable bounds, and built-in operations 
that are rarely used would be gone, but so would the rather substantial 
overhead that those things entail. There'd be a lot more flexibility in 
implementation, which would allow better implementations.

Virtually every array that I write has a fixed size (capacity really) and a 
usage high-water mark (a "length"). Having that generated automatically 
would be usually better than having to reinvent it literally every time I 
program something. (And as you've noticed repeatedly, Ada's type abstraction 
isn't good enough to make it practical to build anything reusable to do 
that.)

>> One could do something similar for records, although I would probably 
>> leave
>> them as in Ada and just allow user-definition of "." (via a getter/setter
>> pair).
>
> Ditto.

???

The basic idea would be to eliminate the huge number of special cases that 
exist in Ada resolution and essentially make *everything* a subprogram call 
at it's heart. Ada did that for enumeration literals and that model makes 
sense for pretty much everything: object usage, indexing, selection, etc. It 
would be much easier to prove that resolution is doing the right thing (I 
don't think that would be practically possible for Ada).

                                 Randy.


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-21  6:45                               ` Dmitry A. Kazakov
@ 2020-08-23  4:52                                 ` Randy Brukardt
  2020-08-23 12:28                                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-23  4:52 UTC (permalink / raw)


"Dmitry A. Kazakov" <[email protected]> wrote in message 
news:[email protected]
> On 21/08/2020 01:33, Randy Brukardt wrote:
>> "Dennis Lee Bieber" <[email protected]> wrote in message
>> news:[email protected]
>>> On Thu, 20 Aug 2020 19:49:44 +0200, "Dmitry A. Kazakov"
>>> <[email protected]> declaimed the following:
>>>
>>>>
>>>> But records and arrays are needed as building blocks of containers. How
>>>> would you get rid of them?
>>>
>>> And likely needed for any embedded or low-level work where they are
>>> mapped to things like (GP) I/O ports or such...
>>
>> Yes, a fixed vector container would be needed for interfacing (probably
>> wouldn't use it for anything else). But there's no reason that can't be
>> provided as a container, so long as representation guarentees (esp.
>> Component_Size) are included. Remember that containers (in Ada 202x) have
>> indexing, aggregates, and all of the useful basic operations. The stuff
>> that's missing is the same stuff that adds a vast amount of complexity to
>> Ada (and possibilities for bugs) - hardly anyone would miss it.
>
> Really? I would miss array conversions, slices, equivalence of same length 
> index ranges, constrained array subtypes etc.

Those things are mostly useful for making work for programmers. Note that 
I'm assuming that Strings are a completely separate abstraction - a UTF-8 
string is not an array and shouldn't be treated as one. (Indexing of 
individual characters being very expensive.) Fixed constrained arrays would 
be available for interfacing (they're not really useful for much else). Note 
that a bounded vector is allocated statically, so there's no extra cost to 
using it (unlike an unbounded vector or string).

                                              Randy.


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-21  7:08                         ` Dmitry A. Kazakov
@ 2020-08-23  5:03                           ` Randy Brukardt
  2020-08-23 12:28                             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2020-08-23  5:03 UTC (permalink / raw)


"Dmitry A. Kazakov" <[email protected]> wrote in message 
news:[email protected]
> On 21/08/2020 01:25, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <[email protected]> wrote in message
>> news:[email protected]
>>> On 20/08/2020 02:13, Randy Brukardt wrote:
>> ...
>>>>> What you do if such an object is allocated via pool-specific access
>>>>> type?
>>>>
>>>> The whole object goes in that pool. The entire mechanism in Janus/Ada 
>>>> is
>>>> built around pools - the stack is represented by a pool object as well 
>>>> as
>>>> various other pools to support the mechanism.
>>>
>>> OK, but then you are back to the problem that you do not know how that
>>> pool works. The user pool might require a certain order of objects 
>>> inside
>>> it and your interference with relocation will break it.
>>
>> Such a pool does not implement the interface as defined in 13.11. It's OK 
>> of
>> course to write a pool that depends on implementation-specific properties
>> (I've done it many times), but such a pool is not usable with portable 
>> Ada
>> code. If the pool allows any sort of allocation at any time, then it will
>> work just fine with the Janus/Ada implementation.
>
> It is a different situation. Such pools are not intended as a general 
> purpose pools. But the type is. In my view an implementation of the type 
> provided by compiler must work in all legal cases. Otherwise it is either 
> language of compiler bug.

There's a third possibility: unrealistic expectations. :-)

The only kind of pool that is not general-purpose is one that is necessarily 
depending on the details of the implementation. Trying to constrain what 
allocations a compiler can do would ensure that a language could not be 
implemented efficiently or flexibly. That's not a language I'd want to use.

...
> It could be very expensive on a multi-core architecture.

I suppose, but that architecture would be lousy for running any 
multi-tasking or parallel program (since any such program is going to need a 
significant amount of synchronization). A lock-free algorithm is usually the 
cheapest possible synchronization on any architecture (it usually includes a 
spin, but the spin is almost never executed).

 > .. I also think
> about scenarios when the object is used inside a protected action. I would 
> not like to see any pool interaction in an interrupt handler!

Interrupt handlers shouldn't be doing anything other than unblocking tasks. 
I think it is a mistake to allow anything else (as there are always problems 
with race conditions if you do so). So no heap possibilities as very little 
is going on.

                                     Randy.


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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-23  4:52                                 ` Randy Brukardt
@ 2020-08-23 12:28                                   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-23 12:28 UTC (permalink / raw)


On 23/08/2020 06:52, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <[email protected]> wrote in message
> news:[email protected]
>> On 21/08/2020 01:33, Randy Brukardt wrote:
>>> "Dennis Lee Bieber" <[email protected]> wrote in message
>>> news:[email protected]
>>>> On Thu, 20 Aug 2020 19:49:44 +0200, "Dmitry A. Kazakov"
>>>> <[email protected]> declaimed the following:
>>>>
>>>>>
>>>>> But records and arrays are needed as building blocks of containers. How
>>>>> would you get rid of them?
>>>>
>>>> And likely needed for any embedded or low-level work where they are
>>>> mapped to things like (GP) I/O ports or such...
>>>
>>> Yes, a fixed vector container would be needed for interfacing (probably
>>> wouldn't use it for anything else). But there's no reason that can't be
>>> provided as a container, so long as representation guarentees (esp.
>>> Component_Size) are included. Remember that containers (in Ada 202x) have
>>> indexing, aggregates, and all of the useful basic operations. The stuff
>>> that's missing is the same stuff that adds a vast amount of complexity to
>>> Ada (and possibilities for bugs) - hardly anyone would miss it.
>>
>> Really? I would miss array conversions, slices, equivalence of same length
>> index ranges, constrained array subtypes etc.
> 
> Those things are mostly useful for making work for programmers. Note that
> I'm assuming that Strings are a completely separate abstraction - a UTF-8
> string is not an array and shouldn't be treated as one. (Indexing of
> individual characters being very expensive.)

That is an implementation detail of a given representation. String of 
any encoding is an array of characters per definition of string.

> Fixed constrained arrays would
> be available for interfacing (they're not really useful for much else).

I would say it is exactly the opposite. Unconstrained arrays are not 
very useful because the operation of changing array length is very rare 
and very expensive (applying your logic).

In most cases a fixed array does the work. Note that among the remaining 
cases, the majority are ones where bounds are still fixed but Ada does 
not support proper initialization or proper aggregation of. The 
remainder of that is very small.

That small part could, again, be covered by bounded arrays, as you 
suggested in another post, if Ada supported propagation of constraints 
in a more effective way than literal discriminants. Presently bounded 
arrays are practically useless because the place where you must specify 
the bounds is never the place where you can determine them.

> Note
> that a bounded vector is allocated statically, so there's no extra cost to
> using it (unlike an unbounded vector or string).

Maybe, but since there will be arrays anyway, why should I suffer 
dealing with messy generics?

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-23  5:03                           ` Randy Brukardt
@ 2020-08-23 12:28                             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-23 12:28 UTC (permalink / raw)


On 23/08/2020 07:03, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <[email protected]> wrote in message
> news:[email protected]
>> On 21/08/2020 01:25, Randy Brukardt wrote:
>>> "Dmitry A. Kazakov" <[email protected]> wrote in message
>>> news:[email protected]
>>>> On 20/08/2020 02:13, Randy Brukardt wrote:
>>> ...
>>>>>> What you do if such an object is allocated via pool-specific access
>>>>>> type?
>>>>>
>>>>> The whole object goes in that pool. The entire mechanism in Janus/Ada
>>>>> is
>>>>> built around pools - the stack is represented by a pool object as well
>>>>> as
>>>>> various other pools to support the mechanism.
>>>>
>>>> OK, but then you are back to the problem that you do not know how that
>>>> pool works. The user pool might require a certain order of objects
>>>> inside
>>>> it and your interference with relocation will break it.
>>>
>>> Such a pool does not implement the interface as defined in 13.11. It's OK
>>> of
>>> course to write a pool that depends on implementation-specific properties
>>> (I've done it many times), but such a pool is not usable with portable
>>> Ada
>>> code. If the pool allows any sort of allocation at any time, then it will
>>> work just fine with the Janus/Ada implementation.
>>
>> It is a different situation. Such pools are not intended as a general
>> purpose pools. But the type is. In my view an implementation of the type
>> provided by compiler must work in all legal cases. Otherwise it is either
>> language of compiler bug.
> 
> There's a third possibility: unrealistic expectations. :-)
> 
> The only kind of pool that is not general-purpose is one that is necessarily
> depending on the details of the implementation. Trying to constrain what
> allocations a compiler can do would ensure that a language could not be
> implemented efficiently or flexibly. That's not a language I'd want to use.
> 
> ...
>> It could be very expensive on a multi-core architecture.
> 
> I suppose, but that architecture would be lousy for running any
> multi-tasking or parallel program (since any such program is going to need a
> significant amount of synchronization). A lock-free algorithm is usually the
> cheapest possible synchronization on any architecture (it usually includes a
> spin, but the spin is almost never executed).
> 
>   > .. I also think
>> about scenarios when the object is used inside a protected action. I would
>> not like to see any pool interaction in an interrupt handler!
> 
> Interrupt handlers shouldn't be doing anything other than unblocking tasks.
> I think it is a mistake to allow anything else (as there are always problems
> with race conditions if you do so). So no heap possibilities as very little
> is going on.

Yes, and this is why light-weight implementations are important. You 
want to take them away while giving no promises, no, actually promising 
that expecting the alternative to work would be: "an unrealistic 
expectation." (:-))

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-08-23  4:48                               ` Randy Brukardt
@ 2020-08-23 12:29                                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2020-08-23 12:29 UTC (permalink / raw)


On 23/08/2020 06:48, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <[email protected]> wrote in message
> news:[email protected]
>> On 21/08/2020 01:30, Randy Brukardt wrote:
> ...
>>> There's no reason that a compiler couldn't "build-in" a simple bounded
>>> vector container as the basic building block.
>>
>> That simply replaces the word "array" with four words "simple bounded
>> vector container." The construct is still there and it is still built-in.
>> The syntax and usability are drastically worse, though.
> 
> ??? The syntax of use is the same (as it is in Ada 2012). Declaration would
> be an instance,

That alone disqualifies it in my eyes.

> about the same length and wordiness as an array declaration.

Plus a dozen of tagged helper types...

> Yes, junk like slices, settable/retrievable bounds, and built-in operations
> that are rarely used would be gone, but so would the rather substantial
> overhead that those things entail. There'd be a lot more flexibility in
> implementation, which would allow better implementations.

These is a vital part of array interface to me. Moreover I want lost of 
other junk there, like ranges being proper types, like multidimensional 
slices/subarrays, indicator sets (to specify array's diagonal) etc.

> Virtually every array that I write has a fixed size (capacity really) and a
> usage high-water mark (a "length"). Having that generated automatically
> would be usually better than having to reinvent it literally every time I
> program something. (And as you've noticed repeatedly, Ada's type abstraction
> isn't good enough to make it practical to build anything reusable to do
> that.)

I agree with that, but disagree with the solution. In my view arrays 
must be 1) generalized, 2) abstracted to support user-defined 
implementations.

The challenge is to have a type system where one could design a 3-band 
matrix type usable where a dense matrix type is expected.

>>> One could do something similar for records, although I would probably
>>> leave
>>> them as in Ada and just allow user-definition of "." (via a getter/setter
>>> pair).
>>
>> Ditto.
> 
> ???
> 
> The basic idea would be to eliminate the huge number of special cases that
> exist in Ada resolution and essentially make *everything* a subprogram call
> at it's heart.

Yes, I agree everything must have a corresponding primitive operation. 
But there are cases when such operations must be static like "." of a 
record types or implemented per delegation to a generalized 
implementation like integer or string literals.

> Ada did that for enumeration literals and that model makes
> sense for pretty much everything: object usage, indexing, selection, etc. It
> would be much easier to prove that resolution is doing the right thing (I
> don't think that would be practically possible for Ada).

I think that not only Ada's, but even C++'s type system, could be 
expressed by means of a more powerful one. After all it is possible to 
write a compiler for both...

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

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

* Re: Proposal: Auto-allocation of Indefinite Objects
  2020-04-03 22:48 Proposal: Auto-allocation of Indefinite Objects Stephen Davies
                   ` (3 preceding siblings ...)
  2020-07-31  9:25 ` Stephen Davies
@ 2020-09-03  4:30 ` linda white
  4 siblings, 0 replies; 47+ messages in thread
From: linda white @ 2020-09-03  4:30 UTC (permalink / raw)


On Saturday, 4 April 2020 04:18:43 UTC+5:30, Stephen Davies  wrote:
> Firstly, apologies if this has already been discussed or,
> more likely, if it's a really stupid idea for some reason
> that I haven't thought of.
> 
> My proposal is that it should (sometimes?) be possible to declare
> objects of indefinite types such as String and have the compiler
> automatically declare the space for them without the programmer
> having to resort to access types.
> 
> Benefits:
> 
> 1. Easier, especially for newbies/students.
> 2. Safer due to reduced use of access types.
> 3. Remove the need to have definite and indefinite verions of generic units.
> 
> It is the 3rd reason that initially got me thinking about this.
> It seems excessive to have two versions of packages just because
> one version can say "Node.Item := New_Item;" but the other has to say
> "Node.Item_Ptr := new Element_Type'(New_Item);".
> 
> It's probably not a good idea for auto-allocation to be the default
> behaviour, so I suggest something like:
> 
>    type Node_Type is record
>       Item : new Element_Type;
>       Prev : Node_Ptr_Type;
>       Next : Node_Ptr_Type;
>    end record;
> 
> If Element_Type is a definite type in the instantiation then
> Node.Item will be a normal object of that type. Otherwise, it is
> implemented as a pointer but the code still treats it as an object.
> The target of the pointer is allocated on assignment of the object.
> The pointer cannot be copied to any other object. Assignments of the
> whole record will perform a deep-copy of the auto-allocated component.
> The target of the Node.Item pointer can be auto-deallocated when Node
> goes out of scope or is deallocated.
> 
> Ok, I've probably missed something obvious and have been wasting my
> time, but at least I've got plenty of time to waste at the moment.

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

end of thread, back to index

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-03 22:48 Proposal: Auto-allocation of Indefinite Objects Stephen Davies
2020-04-03 23:45 ` Stephen Leake
2020-04-04 10:54   ` Jeffrey R. Carter
2020-04-04 20:55     ` Stephen Davies
2020-04-04  8:31 ` Dmitry A. Kazakov
2020-07-27  7:47 ` Yannick Moy
2020-07-27  9:21   ` J-P. Rosen
2020-07-27  9:49     ` Dmitry A. Kazakov
2020-07-27 17:48   ` Brian Drummond
2020-07-27 20:02     ` Dmitry A. Kazakov
2020-07-28 14:28       ` Brian Drummond
2020-07-28 14:59         ` Dmitry A. Kazakov
2020-07-29 15:33           ` Brian Drummond
2020-07-29 16:20             ` Dmitry A. Kazakov
2020-07-30 13:37               ` Stephen Davies
2020-07-30 14:23                 ` Dmitry A. Kazakov
2020-07-30 17:04               ` Brian Drummond
2020-07-30 18:28                 ` Dmitry A. Kazakov
2020-08-10  0:39                   ` Randy Brukardt
2020-08-10  8:57                     ` Dmitry A. Kazakov
2020-08-20  0:10                       ` Randy Brukardt
2020-08-20 17:49                         ` Dmitry A. Kazakov
2020-08-20 20:19                           ` Dennis Lee Bieber
2020-08-20 23:33                             ` Randy Brukardt
2020-08-21  6:45                               ` Dmitry A. Kazakov
2020-08-23  4:52                                 ` Randy Brukardt
2020-08-23 12:28                                   ` Dmitry A. Kazakov
2020-08-20 23:30                           ` Randy Brukardt
2020-08-21  6:46                             ` Dmitry A. Kazakov
2020-08-23  4:48                               ` Randy Brukardt
2020-08-23 12:29                                 ` Dmitry A. Kazakov
2020-08-10  0:31               ` Randy Brukardt
2020-08-10  8:58                 ` Dmitry A. Kazakov
2020-08-20  0:13                   ` Randy Brukardt
2020-08-20 17:49                     ` Dmitry A. Kazakov
2020-08-20 23:25                       ` Randy Brukardt
2020-08-21  7:08                         ` Dmitry A. Kazakov
2020-08-23  5:03                           ` Randy Brukardt
2020-08-23 12:28                             ` Dmitry A. Kazakov
2020-07-27 20:31     ` Jeffrey R. Carter
2020-07-31  9:25 ` Stephen Davies
2020-07-31 10:20   ` Dmitry A. Kazakov
2020-08-01 11:22     ` Stephen Davies
2020-08-01 12:58       ` Dmitry A. Kazakov
2020-08-01 20:35         ` Stephen Davies
2020-08-01 20:56           ` Dmitry A. Kazakov
2020-09-03  4:30 ` linda white

comp.lang.ada

Archives are clonable: git clone --mirror https://archive.legitdata.co/comp.lang.ada

Example config snippet for mirrors


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git