* 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" <mailbox@dmitry-kazakov.de> wrote in message
news:rfs7k4$c83$1@gioia.aioe.org...
> 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" <mailbox@dmitry-kazakov.de> wrote in message
news:rfv3gf$1bbo$1@gioia.aioe.org...
> 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" <mailbox@dmitry-kazakov.de> wrote in message
> news:rfv3gf$1bbo$1@gioia.aioe.org...
>> 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" <mailbox@dmitry-kazakov.de> wrote in message
> news:rfs7k4$c83$1@gioia.aioe.org...
>> 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" <mailbox@dmitry-kazakov.de> wrote in message
news:rgr267$1o1n$1@gioia.aioe.org...
> 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" <mailbox@dmitry-kazakov.de> wrote in message
news:rgr27b$1o1n$2@gioia.aioe.org...
> On 10/08/2020 02:31, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> news:rfs7k4$c83$1@gioia.aioe.org...
>>> 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" <mailbox@dmitry-kazakov.de> wrote in message
> news:rgr27b$1o1n$2@gioia.aioe.org...
>> 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" <mailbox@dmitry-kazakov.de> wrote in message
> news:rgr267$1o1n$1@gioia.aioe.org...
>> 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"
<mailbox@dmitry-kazakov.de> 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
wlfraed@ix.netcom.com 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" <mailbox@dmitry-kazakov.de> wrote in message
news:rhmd3c$1eql$1@gioia.aioe.org...
> 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" <mailbox@dmitry-kazakov.de> wrote in message
news:rhmd3m$1eql$2@gioia.aioe.org...
> On 20/08/2020 02:10, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> news:rgr267$1o1n$1@gioia.aioe.org...
>>> 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" <wlfraed@ix.netcom.com> wrote in message
news:mkmtjflufgmatkk3hp25nvk2hoogun1fis@4ax.com...
> On Thu, 20 Aug 2020 19:49:44 +0200, "Dmitry A. Kazakov"
> <mailbox@dmitry-kazakov.de> 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" <wlfraed@ix.netcom.com> wrote in message
> news:mkmtjflufgmatkk3hp25nvk2hoogun1fis@4ax.com...
>> On Thu, 20 Aug 2020 19:49:44 +0200, "Dmitry A. Kazakov"
>> <mailbox@dmitry-kazakov.de> 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" <mailbox@dmitry-kazakov.de> wrote in message
> news:rhmd3m$1eql$2@gioia.aioe.org...
>> On 20/08/2020 02:10, Randy Brukardt wrote:
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>>> news:rgr267$1o1n$1@gioia.aioe.org...
>>>> 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" <mailbox@dmitry-kazakov.de> wrote in message
> news:rhmd3c$1eql$1@gioia.aioe.org...
>> 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" <mailbox@dmitry-kazakov.de> wrote in message
news:rhnqjf$bga$2@gioia.aioe.org...
> 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" <mailbox@dmitry-kazakov.de> wrote in message
news:rhnqip$bga$1@gioia.aioe.org...
> On 21/08/2020 01:33, Randy Brukardt wrote:
>> "Dennis Lee Bieber" <wlfraed@ix.netcom.com> wrote in message
>> news:mkmtjflufgmatkk3hp25nvk2hoogun1fis@4ax.com...
>>> On Thu, 20 Aug 2020 19:49:44 +0200, "Dmitry A. Kazakov"
>>> <mailbox@dmitry-kazakov.de> 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" <mailbox@dmitry-kazakov.de> wrote in message
news:rhnrtu$rk2$1@gioia.aioe.org...
> On 21/08/2020 01:25, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> news:rhmd3c$1eql$1@gioia.aioe.org...
>>> 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" <mailbox@dmitry-kazakov.de> wrote in message
> news:rhnqip$bga$1@gioia.aioe.org...
>> On 21/08/2020 01:33, Randy Brukardt wrote:
>>> "Dennis Lee Bieber" <wlfraed@ix.netcom.com> wrote in message
>>> news:mkmtjflufgmatkk3hp25nvk2hoogun1fis@4ax.com...
>>>> On Thu, 20 Aug 2020 19:49:44 +0200, "Dmitry A. Kazakov"
>>>> <mailbox@dmitry-kazakov.de> 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" <mailbox@dmitry-kazakov.de> wrote in message
> news:rhnrtu$rk2$1@gioia.aioe.org...
>> On 21/08/2020 01:25, Randy Brukardt wrote:
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>>> news:rhmd3c$1eql$1@gioia.aioe.org...
>>>> 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" <mailbox@dmitry-kazakov.de> wrote in message
> news:rhnqjf$bga$2@gioia.aioe.org...
>> 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, other threads:[~2020-09-03 4:30 UTC | newest]
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox