comp.lang.ada
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: Map iteration and modification
  2024-01-04  4:07  9%                 ` Randy Brukardt
@ 2024-01-04 11:28  0%                   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2024-01-04 11:28 UTC (permalink / raw)


On 2024-01-04 05:07, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:un3bg9$35mhv$1@dont-email.me...

[...]

>> Yes, ordering is an ability to enumerate elements of a set. It is not an
>> artifact it is the sole semantics of.
> 
> Iteration is not necessarily enumeration. It is applying an operation to all
> elements, and doing that does not require an order.

That is not iteration, it is unordered listing, a totally useless thing 
because the result is the same unordered set.

You could not implement it without prior ordering of the elements you 
fed to the threads. If the threads picked up elements concurrently there 
would be no way to do that without ordering elements into a taken / not 
yet taken order. Hell, you cannot even get an element from a truly 
unordered set, no way! If the programmer tried to make any use of the 
listing he would again have to impose ordering when collecting results 
per some shared object.

The unordered listing is a null operation without ordering.

>> The key difference is that index does not refer any element. It is
>> container + index that do.
> 
> That's not a "key difference". That exactly how one should use cursors,
> especially in Ada 2022. The Ada containers do have cursor-only operations,
> but those should be avoided since it is impossible to provide useful
> contracts for those operations (the container is unknown, so the world can
> be modified, which is bad for parallelism and understanding). Best to
> consider those operations obsolete. (Note that I was *always* against the
> cursor-only operations in the containers.)
> 
> So, using a cursor implies calling an operation that includes the container
> of its parameter.

OK. It is some immensely over-designed index operation, then! (:-)) So, 
my initial question is back, why all that overhead? When you cannot do 
elementary things like preserving your indices from a well-defined set 
of upon deleting elements with indices outside that set?

>>>> I don't see anything that is not already there. What are reasons for not
>>>> providing:
>>>>
>>>>      M (n)       [ e.g. M (n).Key, M (n).Value ]
>>>>      M (n1..n2)  [ in mutable contexts too ]
>>>>      M'First
>>>>      M'Last
>>>>      M1 & M2     [ M1 or M2 ]
>>>>
>>>> They are all well-defined and useful operations.
>>>
>>> Performance.
>>
>> Irrelevant so long it does not tamper implementations of other operations.
> 
> Exactly. These operations, especially slicing, have a huge impact on the
> cost of parameter passing for arrays (whether or not they are used). And
> that's a pretty fundamental operation.

It is not slicing it is dynamically constrained arrays which are 
required anyway. A general problem of language design is how to treat 
statically known constraints effectively.

Ada arrays are pretty good to me. Note, I am saying that after years of 
using Ada arrays for interfacing C! Yes, I would like having more 
support for flattening arrays, but the mere fact that Ada can interface 
C using *in-place* semantics invalidates your point.

> Specifically, the containers are separate from Ada.

Not really. Like STL with C++ it massively influenced the language 
design motivating adding certain language features and shifting general 
language paradigm in certain direction.

>> Usability always trumps performance.
> 
> That's the philosophy of languages like Python, not Ada.

Ah, this is why Python is totally unusable? (:-))

Ada is usable and performant because of right abstractions it deploys. 
If you notice performance problems then, maybe, just my guess, you are 
using a wrong abstraction?

>> And again, looking at the standard containers and all these *tagged*
>> *intermediate* objects one needs in order to do elementary things, I kind
>> of in doubts... (:-))
> 
> The standard containers were designed to make *safe* containers with decent
> performance.

Well, we always wish the best... (:-))

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

^ permalink raw reply	[relevance 0%]

* Re: Map iteration and modification
  @ 2024-01-04  4:07  9%                 ` Randy Brukardt
  2024-01-04 11:28  0%                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2024-01-04  4:07 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:un3bg9$35mhv$1@dont-email.me...
> On 2024-01-03 04:15, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> news:umotm2$18lqm$1@dont-email.me...
...
> The meaning of the word "iterate" is doing something (e.g. visiting an 
> element) again. That *is* an order.

The order is an artifact. One logically visits all of the elements at the 
same time (certainly in an unordered container like a general map).

>> Indeed, logically, all of
>> the elements are presented at the same time (and parallel iteration 
>> provides
>> an approximation of that).
>
> Parallel iteration changes nothing because involved tasks are enumerated 
> and thus ordered as well.

Nonsense. There is no interface in Ada to access logical threads (the ones 
created by the parallel keyword).

>> If you try to enforce an order on things that don't require it, you end 
>> up
>> preventing useful parallelism (practically, at least, no one has 
>> succeeded
>> at providing useful parallelism to sequential code and people have been
>> trying for about 50 years -- they were trying when I was a university
>> student in the late 1970s).
>
> Ordering things does not prevent parallelism.

Yes it does, because it adds unnecessary constraints. It's those constraints 
that make parallelizing normal sequenatial code hard. A parallelizer has to 
guess which ones are fundamental to the code meaning and which ones are not.

...
>> Ordering is a separate concept, not always
>> needed (certainly not in basic structures like maps, sets, and bags).
>
> Right. But no ordering means no iteration, no foreach etc. If I can 
> iterate, that I can create an ordered set of (counter, element) pairs. 
> Done.
>
>>> Yes position is a property of enumeration.
>>
>> Surely not. This is a basis for my disagrement with you here.
>
> Then you are disagreeing with core mathematics... (:-))

You are adding an unnecessary property to the concept of iteration. 
Iteration does not necessarily imply enumeration (it can, of course). 
Iteration /= enumeration.

...
>> The order is
>> an artifact of doing it an inherently parallel operation sequentally.
>
> Yes, ordering is an ability to enumerate elements of a set. It is not an 
> artifact it is the sole semantics of.

Iteration is not necessarily enumeration. It is applying an operation to all 
elements, and doing that does not require an order. Some specific operations 
might require an order, and clearly for those one needs to use a data 
structure that inherently has an order.
...
>> So long as you are using arrays, you are using referential semantics. The
>> only way to avoid it is to directly embed an object directly in an 
>> enclosing
>> object (as in a record), and that doesn't work for many problems.
>
> The key difference is that index does not refer any element. It is 
> container + index that do.

That's not a "key difference". That exactly how one should use cursors, 
especially in Ada 2022. The Ada containers do have cursor-only operations, 
but those should be avoided since it is impossible to provide useful 
contracts for those operations (the container is unknown, so the world can 
be modified, which is bad for parallelism and understanding). Best to 
consider those operations obsolete. (Note that I was *always* against the 
cursor-only operations in the containers.)

So, using a cursor implies calling an operation that includes the container 
of its parameter.

> From the programming POV it is about avoiding hidden states when you try 
> to sweep the container part under the rug.

That's easily avoided -- don't use the obsolete operations. (And a style 
tool like Jean-Pierre's can enforce that for you.)

>>> I don't see anything that is not already there. What are reasons for not
>>> providing:
>>>
>>>     M (n)       [ e.g. M (n).Key, M (n).Value ]
>>>     M (n1..n2)  [ in mutable contexts too ]
>>>     M'First
>>>     M'Last
>>>     M1 & M2     [ M1 or M2 ]
>>>
>>> They are all well-defined and useful operations.
>>
>> Performance.
>
> Irrelevant so long it does not tamper implementations of other operations.

Exactly. These operations, especially slicing, have a huge impact on the 
cost of parameter passing for arrays (whether or not they are used). And 
that's a pretty fundamental operation.

>> If all of these things are user-definable, then one has to use
>> subprogram calls to implement all of them. That can be very expensive,
>> particularly in the case of mutable operations (and mutable slices are 
>> the
>> worst of all).
>
> But better, faster, safer when implemented ad-hoc by the programmer?

As with all programming problems, you can only have two of the three. ;-)

If the underlying programming language is already better and safer, that 
extends to user-written operations. (If it doesn't, it is a failure.)

...
...
>> I think it is much better to get rid of most of these operations as 
>> built-in
>> things and just let the programmer build their own operations as needed.
>
> Well, if you'd proposed throwing containers out the standard library I 
> would believe that you believe in that... (:-))

The standard library is not part of the programming language. It's a 
necessary adjunct, but it could be completely replaced without changing the 
language at all. It's necessary mainly so that basic operations are provided 
in the same way by all implementations, but there is little requirement to 
use it.

Specifically, the containers are separate from Ada. Plenty of programmers 
use their own container libraries, with different performance and safety 
profiles. That's expected and intended. There is no one-size-fits-all (or 
even one-size-fits-many) container library.

>> That keeps the cost confined to those who use them. Distributed overhead 
>> is
>> the worst kind, and slices in particular have a boatload of that 
>> overhead.
>
> Usability always trumps performance.

That's the philosophy of languages like Python, not Ada. If you truly 
believe this, then you shouldn't be using Ada at all, since it makes lots of 
compromises to usability in order to get performance.

> And again, looking at the standard containers and all these *tagged* 
> *intermediate* objects one needs in order to do elementary things, I kind 
> of in doubts... (:-))

The standard containers were designed to make *safe* containers with decent 
performance. As I noted, they're not a built-in part of the programming 
language, and as such have no impact on the performance of the language 
proper. One could easily replace them with an unsafe design to get maximum 
performance -- but that would have to return pointers to elements, and 
you've said you don't like referential semantics. So you would never use 
those.

You also can avoid all of the "tagged objects" (really controlled objects) 
by using function Element to get a copy of the element rather than some sort 
of reference to it. That's preferred if it doesn't cost too much for your 
application.

                       Randy. 


^ permalink raw reply	[relevance 9%]

* Re: Map iteration and modification
  2024-01-01 19:27  8%             ` G.B.
@ 2024-01-01 20:55  0%               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2024-01-01 20:55 UTC (permalink / raw)


On 2024-01-01 20:27, G.B. wrote:
> On 29.12.23 17:52, Dmitry A. Kazakov wrote:
> 
>>> Suppose that there is a way of orderly proceeding from one item to 
>>> the next.
>>> It is probably known to the implementation of map. Do single steps
>>> guarantee transitivity, though, so that an algorithm can assume the
>>> order to be invariable?
>>
>> An insane implementation can expose random orders each time.
> 
> An implementation order should then not be exposed, right?

IMO, an order should be exposed. Not necessarily the "implementation 
order" whatever that might mean.

> What portable benefits would there be when another interface
> is added to that of map, i.e., to Ada containers for general use?

It is same benefit Ada arrays have over C's T* pointers and arithmetic 
of. Cursor is merely a fat pointer.

> Would it not be possible to get these benefits using a different
> approach? I think the use case is clearly stated:
> 
> First, find Cursors in map =: C*.
> Right after that, Delete from map all nodes referred to by C*.

Right. Find cursors, store cursors in another container, iterate that 
container deleting elements of the first. Now, consider that the cursors 
in the second container become invalid (dangling pointers). If you 
wanted to delete them immediately from the second container, you would 
return the square one! (:-))

With a positional access interface it would be just (pure Ada 95):

    for Index in reverse 1..Number_Of_Elements (Container) loop
       if Want_To_Delete (Get (Container (Index))) then
          Delete (Container, Index);
       end if;
    end loop;

> For deleting, this thread has shown a loop that calls Delete
> multiple times right after collecting the cursors.
> And it is boilerplate text.  Could Maps be improved for this use case?

See above.

> [Bulk deletion] We do get bulk insertion in containers.  Also,
> A.18.2 already has bulk Delete operations.  Similarly,
> the Strings packages have them.
> 
> [No thread safety needed] If standard Ada maps are usually operated
> by just one task, stability of Cursors is predictable.
> 
> Then, with or without automatic management of storage,
> when My_Map is from an instance of Ordered_Map,
> 
>     Start  := In_13th_Floor (My_Map.Ceiling (13.0));
>     Finish := In_13th_Floor (My_Map.Floor (Fxd'Pred (14.0)));
>     My_Map.Delete (
>        From    => Start,
>        Through => Finish);

The case is more general: delete pairs satisfying certain criterion.

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

^ permalink raw reply	[relevance 0%]

* Re: Map iteration and modification
  @ 2024-01-01 19:27  8%             ` G.B.
  2024-01-01 20:55  0%               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: G.B. @ 2024-01-01 19:27 UTC (permalink / raw)


On 29.12.23 17:52, Dmitry A. Kazakov wrote:

>> Suppose that there is a way of orderly proceeding from one item to the next.
>> It is probably known to the implementation of map. Do single steps
>> guarantee transitivity, though, so that an algorithm can assume the
>> order to be invariable?
> 
> An insane implementation can expose random orders each time.

An implementation order should then not be exposed, right?
What portable benefits would there be when another interface
is added to that of map, i.e., to Ada containers for general use?
Would it not be possible to get these benefits using a different
approach? I think the use case is clearly stated:

First, find Cursors in map =: C*.
Right after that, Delete from map all nodes referred to by C*.


> Unless removing element invalidates all cursors. Look, insanity has no bounds. Cursors AKA pointers are as volatile as positions in certain implementations. Consider a garbage collector running after removing a pair and shuffling remaining pairs in memory.
> 
>> Maybe the bulk operations of some DBMS' programming
>> interfaces work just like this, for practical reasons.
>> Ada 202x' Ordered_Maps might want to add a feature ;-)
>>
>>       procedure Delete (Container : in out Map;
>>                         From      : in out Cursor;
>>                         To        : in out Cursor);
> 
> Here you assume that cursors are ordered and the order is preserved from call to call. Even if From and To are stable the range From..To can include random pairs in between.

Yes, given the descriptions of Ordered_Maps, so long as there is no
tampering, a Cursor will respect an order. Likely the one that the
programmer has in mind.

For deleting, this thread has shown a loop that calls Delete
multiple times right after collecting the cursors.
And it is boilerplate text.  Could Maps be improved for this use case?

[Bulk deletion] We do get bulk insertion in containers.  Also,
A.18.2 already has bulk Delete operations.  Similarly,
the Strings packages have them.
  
[No thread safety needed] If standard Ada maps are usually operated
by just one task, stability of Cursors is predictable.

Then, with or without automatic management of storage,
when My_Map is from an instance of Ordered_Map,

    Start  := In_13th_Floor (My_Map.Ceiling (13.0));
    Finish := In_13th_Floor (My_Map.Floor (Fxd'Pred (14.0)));
    My_Map.Delete (
       From    => Start,
       Through => Finish);

where
    function In_13th_Floor (C : Cursor) return Cursor
    --  C, if the key at C is in [13.0, 14.0), No_Element otherwise

should therefore do the right thing, in that nothing
is left to chance.

^ permalink raw reply	[relevance 8%]

* What I do wrong here?
@ 2023-09-22  6:25  9% reinert
  0 siblings, 0 replies; 200+ results
From: reinert @ 2023-09-22  6:25 UTC (permalink / raw)


-- Assume the following ordered_map:

     package n_cells1_p is new ada.containers.ordered_maps
           (key_type => celltype1_t, element_type => Natural);
      use n_cells1_p;
      n_cells1 : n_cells1_p.map;

 -- This statemanet is OK according to latest gnat (latest alire release):
        n_cells1(cells1(e.id).type1) := n_cells1(cells1(e.id).type1) + 1;

-- But the compiler does not like this:
        n_cells1(cells1(e.id).type1) := @ + 1;

(giving messages: 
error: expected type universal integer 
error: found private type "Ada.Containers.Ordered_Maps.Reference_Type" ...

OK, I can live with the first alternative, but I would like to know...

reinert

^ permalink raw reply	[relevance 9%]

* Re: Aggregate with derived types.
  2023-09-14 15:31  0% ` Jeffrey R.Carter
@ 2023-09-14 20:00  0%   ` Blady
  0 siblings, 0 replies; 200+ results
From: Blady @ 2023-09-14 20:00 UTC (permalink / raw)


Le 14/09/2023 à 17:31, Jeffrey R.Carter a écrit :
> On 2023-09-14 16:02, Blady wrote:
>>
>>       1. with Ada.Containers.Vectors;
>>       2. with Ada.Text_IO;
>>       3. procedure test_20230914_derived_agg is
>>       4.    package My_Float_Lists is new Ada.Containers.Vectors 
>> (Positive, Float);
>>       5.    subtype My_Float_List1 is My_Float_Lists.Vector;
>>       6.    type My_Float_List2 is new My_Float_Lists.Vector with null 
>> record;
>>       7.    ML1 : My_Float_List1 := [-3.1, -6.7, 3.3, -3.14, 0.0];
>>       8.    ML2 : My_Float_List2 := ([-3.1, -6.7, 3.3, -3.14, 0.0] 
>> with null record);
>>                                      |
>>          >>> error: no unique type for this aggregate
> 
> IIUC, you have to qualify the value:
> 
> (My_Float_List1'[-3.1, -6.7, 3.3, -3.14, 0.0] with null record)
> 
> or
> 
> (My_Float_Lists.Vector'[-3.1, -6.7, 3.3, -3.14, 0.0] with null record)
> 
> (not tested)

Thanks Jeff, both proposals are compiled ok by GNAT.

I wonder why the float list aggregate isn't inferred by the compiler and 
need some help with a qualification.

^ permalink raw reply	[relevance 0%]

* Re: Aggregate with derived types.
  2023-09-14 14:02  8% Aggregate with derived types Blady
@ 2023-09-14 15:31  0% ` Jeffrey R.Carter
  2023-09-14 20:00  0%   ` Blady
  0 siblings, 1 reply; 200+ results
From: Jeffrey R.Carter @ 2023-09-14 15:31 UTC (permalink / raw)


On 2023-09-14 16:02, Blady wrote:
> 
>       1. with Ada.Containers.Vectors;
>       2. with Ada.Text_IO;
>       3. procedure test_20230914_derived_agg is
>       4.    package My_Float_Lists is new Ada.Containers.Vectors (Positive, Float);
>       5.    subtype My_Float_List1 is My_Float_Lists.Vector;
>       6.    type My_Float_List2 is new My_Float_Lists.Vector with null record;
>       7.    ML1 : My_Float_List1 := [-3.1, -6.7, 3.3, -3.14, 0.0];
>       8.    ML2 : My_Float_List2 := ([-3.1, -6.7, 3.3, -3.14, 0.0] with null 
> record);
>                                      |
>          >>> error: no unique type for this aggregate

IIUC, you have to qualify the value:

(My_Float_List1'[-3.1, -6.7, 3.3, -3.14, 0.0] with null record)

or

(My_Float_Lists.Vector'[-3.1, -6.7, 3.3, -3.14, 0.0] with null record)

(not tested)

-- 
Jeff Carter
"[M]any were collected near them, ... to
enjoy the sight of a dead young lady, nay,
two dead young ladies, for it proved twice
as fine as the first report."
Persuasion
155

^ permalink raw reply	[relevance 0%]

* Aggregate with derived types.
@ 2023-09-14 14:02  8% Blady
  2023-09-14 15:31  0% ` Jeffrey R.Carter
  0 siblings, 1 reply; 200+ results
From: Blady @ 2023-09-14 14:02 UTC (permalink / raw)


Hello,

I want to extend a container type like Vectors, I've written:
   type My_Float_List2 is new My_Float_Lists.Vector with null record;

But the initialization gives an error line 6:

      1. with Ada.Containers.Vectors;
      2. with Ada.Text_IO;
      3. procedure test_20230914_derived_agg is
      4.    package My_Float_Lists is new Ada.Containers.Vectors 
(Positive, Float);
      5.    subtype My_Float_List1 is My_Float_Lists.Vector;
      6.    type My_Float_List2 is new My_Float_Lists.Vector with null 
record;
      7.    ML1 : My_Float_List1 := [-3.1, -6.7, 3.3, -3.14, 0.0];
      8.    ML2 : My_Float_List2 := ([-3.1, -6.7, 3.3, -3.14, 0.0] with 
null record);
                                     |
         >>> error: no unique type for this aggregate
      9. begin
     10.    Ada.Text_IO.Put_Line (ML1.Element (3)'Image);
     11.    Ada.Text_IO.Put_Line (ML2.Element (3)'Image);
     12. end test_20230914_derived_agg;

The RM says:
4.3.2 Extension Aggregates
1   [An extension_aggregate specifies a value for a type that is a record
extension by specifying a value or subtype for an ancestor of the type,
followed by associations for any components not determined by the
ancestor_part.]
                          Language Design Principles
1.a         The model underlying this syntax is that a record extension can
             also be viewed as a regular record type with an ancestor 
"prefix".
             The record_component_association_list corresponds to 
exactly what
             would be needed if there were no ancestor/prefix type. The
             ancestor_part determines the value of the ancestor/prefix.
                                    Syntax
2       extension_aggregate ::=
             (ancestor_part with record_component_association_list)
3       ancestor_part ::= expression | subtype_mark

It is not so clear for me what could a unique type?
Any clue?

Thanks Pascal.


^ permalink raw reply	[relevance 8%]

* Re: project euler 26
  2023-09-09  9:32  4%                                       ` Dmitry A. Kazakov
@ 2023-09-10  1:20  0%                                         ` Ben Bacarisse
  0 siblings, 0 replies; 200+ results
From: Ben Bacarisse @ 2023-09-10  1:20 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On 2023-09-09 02:25, Ben Bacarisse wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

>>> [rant on]
>>> An Ada programmer would just write a loop.
>> Yes, that's fine.  Different languages have different objectives.  Just
>> write the empty range test and the loop you need for each kind of
>> collection.
>
> You can loop in Ada over empty ranges, no problem.

Yes, but the problem in hand (maximum of F over X) should raise an error
on an empty X.  I know there are other options, but you chose to
raise an error so that's the design I was talking about.

>> That was definitely the way things were done in the 80s.
>
> Yes, before the Dark Ages of Computing...

Eh?  There have been repeated updates to the Ada language.  Are they
taking Ada into the dark ages?  If so, what was the golden age of Ada
when its design was perfect for numerical algorithms?

>>> As I said you think in a wrong direction of abstracting the language
>>> "finding maximum" rather than the problem space, e.g. generalization to
>>> other bases, other mathematical structures etc.
>> Generalising to an arbitrary base is local to the function that finds
>> the answer for one element.  It's an entirely separate axis of
>> generalisation to that of where the elements come from.
>> It's interesting to me that you consider one simply wrong and the other
>> natural.
>
> Because one is a software design artifact and another is the result of
> problem space analysis.

Which one the wrong one?

>> In some languages the "wrong" one does not even merit
>> consideration as it's just there for free.
>
> Being a part of design it has all possible merits to consider and then
> reject it. That is in the position of a puzzle solver. Now in the position
> of a library designer, the Ada standard library has an [informal] interface
> that supports what you wanted:

Well, there has been some confusion over that, but from what I
understand of the code below, adding in a function to maximise would be
simple.

> 1. Cursor
> 2. Key at the cursor
> 3. Element at the cursor
> 4. Iterate procedure
>
> So, for the Ada standard library it might look like this:
>
> generic
>    type Container_Type (<>) is limited private;
>    type Element_Type is private;
>    type Key_Type is private;
>    type Cursor_Type is private;
>    with function "<" (Left, Right : Element_Type) return Boolean is <>;
>    with function Key (Position : Cursor_Type) return Key_Type is <>;
>    with function Element
>                  (  Position  : Cursor_Type
>                  )  return Element_Type is <>;
>    with procedure Iterate
>                   (  Container : Container_Type;
>                      Process   : not null access procedure
>                                  (Position : Cursor_Type)
>                   )  is <>;
> function Generic_Container_Maximum_At (Container : Container_Type)
>    return Key_Type;
>
> function Generic_Container_Maximum_At (Container : Container_Type)
>    return Key_Type is
>    Found  : Boolean := False;
>    Max    : Element_Type;
>    Result : Key_Type;
>    procedure Walker (Position : Cursor_Type) is
>    begin
>       if Found then
>          if Max < Element (Position) then
>             Result := Key (Position);
>             Max    := Element (Position);
>          end if;
>       else
>          Result := Key (Position);
>          Max    := Element (Position);
>          Found  := True;
>       end if;
>    end Walker;
> begin
>    Iterate (Container, Walker'Access);
>    if Found then
>       return Result;
>    else
>       raise Constraint_Error with "Empty container";
>    end if;
> end Generic_Container_Maximum_At;
>
> Instantiation:
>
>    package Integer_Maps is
>       new Ada.Containers.Ordered_Maps (Integer, Integer);
>    use Integer_Maps;
>    function Integer_Map_Max is
>       new Generic_Container_Maximum_At (Map, Integer, Integer, Cursor);

This is probably the closest we can get to a universal solution.
Vectors don't have a Key function but I am sure I could find out what
should be provided there.

Thanks.

I agree that is does not feel worth it.  Just write the loop our each time.

-- 
Ben.

^ permalink raw reply	[relevance 0%]

* Re: project euler 26
  2023-09-09  0:25  0%                                     ` Ben Bacarisse
@ 2023-09-09  9:32  4%                                       ` Dmitry A. Kazakov
  2023-09-10  1:20  0%                                         ` Ben Bacarisse
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2023-09-09  9:32 UTC (permalink / raw)


On 2023-09-09 02:25, Ben Bacarisse wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On 2023-09-08 03:32, Ben Bacarisse wrote:
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>
>>>> On 2023-09-07 01:32, Ben Bacarisse wrote:
>>>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>>>
> I wanted the maximum of a function over a collection (range, array, map,
> etc).  In some languages, collections can be scanned so you don't need
> to know where the data come from.

Hmm, the thing we discussed was a maximum element in array or map rather 
than a maximum of a function over the *domain* set of array or map. In a 
typed language array /= domain of array.

>>>> Then you would pass Has_Element for it. For integers you would use wrapped
>>>> X'Valid (there is no Integer'Valid, unfortunately. Only X'Valid where X is
>>>> an object).
>>> It's definitely getting what I call cumbersome.
>>
>> Yes, because you try too hard to make it work where it probably should
>> not.
> 
> If you think a resuable Ada function that can find the maximum of some F
> over some 'collection' X is possible, I'd like to see how it's done.

To start with, no such function exists. Not in a typed language. Note 
that a generic function is not a function. So instead we must consider 
language constructs for the purpose. Generic instantiation is one of 
them, some class might be another, but in Ada we just use loops. (And 
yes, people liking writing programs while standing on their heads, may 
use recursion... (:-))

> I
> can do it for some kinds of X but I have no idea how general it can be
> made in Ada.  I think the answer is either that it can't be very
> general, or to make it very general is too much work, or that one should
> not be trying in the first place.

The limits of generality are defined by the interfaces. In Ada types are 
designed to implement needed interfaces upfront. If you want to do that 
after the fact, you need some other adapter types to shove an existing 
type into something it was not designed for.

>>> I don't think this is incoherent.  The Haskell libraries ensure that any
>>> collection that is logically foldable is indeed foldable.
>>
>> Ada arrays and library containers do not share interfaces.
> 
> I was pretty sure that was the case.  Thanks for confirming.  I think
> that means there can be no truly generic solution.  But maybe it's
> possible at least for all container types in the library?

If a library is designed with this purpose in mind, that is trivial as 
you just pointed out. All collection types in the library would 
implement the required interface. End of story.

> (But I note
> that if you think it /shouldn't/ be done, I won't expect you to show me
> how.)

That is not a language question. It is a question of the library design. 
What if the library did not follow the desired design? That would be a 
language question and Ada offers some means, but not enough from my 
point of view due to the limitation of its type system.

>> Should the language allow adding
>> ad-hoc interfaces to existing types. Yes, and this is possible in Ada in
>> some very uncomfortable AKA cumbersome way, which is why "finding maximum"
>> is not a worthy abstraction in Ada.
> 
> I suspected one might have to extend the interfaces.

You cannot in a strongly typed language without breaking too much 
things. You must create another type related to the old one and 
implementing the new interface (superclass). That would do the trick. 
Ada cannot this, so you go for the poor man's substitute: a mix-in. I.e. 
you create a new type that references an object of the old type. E.g. 
see array cursors example in my earlier post.

>>> What closure is required for a function composition?  There is no
>>> environment to "close over".
>>
>> In Ada a function can use anything visible at its declaration point and at
>> the location of its body. You can even declare a function inside a
>> recursively called function and let it see local variables of each
>> recursive call, in effect having an infinite set of functions.
> 
> At the point where I want Period.Element I can write the (almost)
> one-line function that takes a Cursor and returns Period(Element(C))
> entirely mechanically.  Can't the compiler do that?

No.

(Ada indeed composes functions in some limited number of cases, e.g. an 
explicit type conversion of [in] out arguments. But these are predefined.)

> Note I'm not asking if it /should/ (it may not be "Ada-like" to do
> that).  I'm just curious if there really is a technical reason it can't
> be done.

Actually compositions might be useful in many cases and adapting 
interfaces is one of them.

>>> That's a lot just to use something that is supposed to be reusable.
>>
>> [rant on]
>> An Ada programmer would just write a loop.
> 
> Yes, that's fine.  Different languages have different objectives.  Just
> write the empty range test and the loop you need for each kind of
> collection.

You can loop in Ada over empty ranges, no problem.

> That was definitely the way things were done in the 80s.

Yes, before the Dark Ages of Computing...

>>> It only occurred to me after writing the non-generic solution.  I
>>> remember Ada as being something of a pioneer in it's attempt to provide
>>> generic solutions, so I wondered how far things had come.  I don't think
>>> something really widely reusable is possible in this case.
>>
>> As I said you think in a wrong direction of abstracting the language
>> "finding maximum" rather than the problem space, e.g. generalization to
>> other bases, other mathematical structures etc.
> 
> Generalising to an arbitrary base is local to the function that finds
> the answer for one element.  It's an entirely separate axis of
> generalisation to that of where the elements come from.
> 
> It's interesting to me that you consider one simply wrong and the other
> natural.

Because one is a software design artifact and another is the result of 
problem space analysis.

> In some languages the "wrong" one does not even merit
> consideration as it's just there for free.

Being a part of design it has all possible merits to consider and then 
reject it. That is in the position of a puzzle solver. Now in the 
position of a library designer, the Ada standard library has an 
[informal] interface that supports what you wanted:

1. Cursor
2. Key at the cursor
3. Element at the cursor
4. Iterate procedure

So, for the Ada standard library it might look like this:

generic
    type Container_Type (<>) is limited private;
    type Element_Type is private;
    type Key_Type is private;
    type Cursor_Type is private;
    with function "<" (Left, Right : Element_Type) return Boolean is <>;
    with function Key (Position : Cursor_Type) return Key_Type is <>;
    with function Element
                  (  Position  : Cursor_Type
                  )  return Element_Type is <>;
    with procedure Iterate
                   (  Container : Container_Type;
                      Process   : not null access procedure
                                  (Position : Cursor_Type)
                   )  is <>;
function Generic_Container_Maximum_At (Container : Container_Type)
    return Key_Type;

function Generic_Container_Maximum_At (Container : Container_Type)
    return Key_Type is
    Found  : Boolean := False;
    Max    : Element_Type;
    Result : Key_Type;
    procedure Walker (Position : Cursor_Type) is
    begin
       if Found then
          if Max < Element (Position) then
             Result := Key (Position);
             Max    := Element (Position);
          end if;
       else
          Result := Key (Position);
          Max    := Element (Position);
          Found  := True;
       end if;
    end Walker;
begin
    Iterate (Container, Walker'Access);
    if Found then
       return Result;
    else
       raise Constraint_Error with "Empty container";
    end if;
end Generic_Container_Maximum_At;

Instantiation:

    package Integer_Maps is
       new Ada.Containers.Ordered_Maps (Integer, Integer);
    use Integer_Maps;
    function Integer_Map_Max is
       new Generic_Container_Maximum_At (Map, Integer, Integer, Cursor);

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

^ permalink raw reply	[relevance 4%]

* Re: project euler 26
  @ 2023-09-09  8:13  8%                                   ` G.B.
  0 siblings, 0 replies; 200+ results
From: G.B. @ 2023-09-09  8:13 UTC (permalink / raw)


On 08.09.23 23:02, Ben Bacarisse wrote:
> "G.B." <bauhaus@notmyhomepage.invalid> writes:
> 
>> On 07.09.23 01:32, Ben Bacarisse wrote:
>>
>>
>>> A fix (though it's not really ideal) would be to use function
>>> composition here (inventing . as the composition operator):
>>
>> Hm. A stateful, composed function that needs to be applied
>> in a certain way. Is that so different from  calling interface
>> subprograms of a certain type?
> 
> There was nothing stateful (as I understand the term) in either function
> being composed.

The "apparatus" that the computation needs in order to remember
"max so far" looks like part of its state to me. Somehow
"the function" needs to operate this state and evaluate it.
Extend this to:
- find the maximum of [the maxima of] these n collections
- find the maximum in this stream at 10 seconds from now.

Is it possible, or practical, to define a pure function so that
calling it will remember the needed information, n >= 0
being arbitrary?

>> So, does type composition help?
> 
> My turn to guess now: you are not being serious?  I see no connection to
> monads or type composition. 

In the following sense:
There is an object of type So_Far that can remember
objects of any type T, them coming from collections
of type C-of-T.

> And why bring C++ into it?

It's already there, you mentioned the pair of iterators, and
there is std::max_element() which finds the greatest element
in any range based solely on these, and optionally using a generic
comparison.
There are similar things in Dmitry's packages. A key difference
seems to be that Ada's Cursors are tied to a specific collection.
I don't know of any convenient way around this, maybe because
type Cursor is just private in every Ada.Containers.Xyz and
there is no common type name for them, or for what some
algorithm might need them to have in common.

I'm not sure if the new Ada.Iterator_Interfaces (LRM 5.5.1)
could solve this, also because I really don't know that yet.
But it looks like I'd need instances of specific containers
for instantiation. (That being consistent with Ada's approach
to the STL, I think.)


^ permalink raw reply	[relevance 8%]

* Re: project euler 26
  2023-09-08  7:23  0%                                   ` Dmitry A. Kazakov
@ 2023-09-09  0:25  0%                                     ` Ben Bacarisse
  2023-09-09  9:32  4%                                       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Ben Bacarisse @ 2023-09-09  0:25 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On 2023-09-08 03:32, Ben Bacarisse wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>> On 2023-09-07 01:32, Ben Bacarisse wrote:
>>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>>
>>>>> On 2023-09-06 17:16, Ben Bacarisse wrote:
>>>>>
>>>> Second, if I try to use a Vector rather than an Ordered_Map, I am told
>>>> that:
>>>> test2.adb:97:05: error: instantiation error at line 12
>>>> test2.adb:97:05: error: no visible subprogram matches the specification for "<"
>>>> It would seem that vector cursors can't be compared using < (at least by
>>>> default).  Maybe the installation needs more arguments.
>>>
>>> Vector has a proper index type. All you have to do is. Given
>>>
>>>     package Integer_Vectors is
>>>        new Ada.Containers.Vectors (Integer, Integer);
>>>
>>> Wrap Element into a function:
>>>
>>>     V : Integer_Vectors.Vector;
>>>     function Element (Index : Integer) return Integer is
>>>     begin
>>>        return V.Element (Index);
>>>     end Element;
>>>     ...
>>>
>>> and use the wrapper.
>> Sure, but the hope was to write something that does not need new
>> code for new situations.  That's what makes it reusable.
>
> Why should it be? You wanted to find maximum of a function. Vector is
> not a function.

I wanted the maximum of a function over a collection (range, array, map,
etc).  In some languages, collections can be scanned so you don't need
to know where the data come from.

>>> Then you would pass Has_Element for it. For integers you would use wrapped
>>> X'Valid (there is no Integer'Valid, unfortunately. Only X'Valid where X is
>>> an object).
>> It's definitely getting what I call cumbersome.
>
> Yes, because you try too hard to make it work where it probably should
> not.

If you think a resuable Ada function that can find the maximum of some F
over some 'collection' X is possible, I'd like to see how it's done.  I
can do it for some kinds of X but I have no idea how general it can be
made in Ada.  I think the answer is either that it can't be very
general, or to make it very general is too much work, or that one should
not be trying in the first place.

(I put 'collection' in quotes because I know that's an Ada term but I
don't necessarily want to restrict the solution to how Ada uses the
term.  For example, I don't think native arrays are collections in the
formal Ada library sense.)

>> I don't think this is incoherent.  The Haskell libraries ensure that any
>> collection that is logically foldable is indeed foldable.
>
> Ada arrays and library containers do not share interfaces.

I was pretty sure that was the case.  Thanks for confirming.  I think
that means there can be no truly generic solution.  But maybe it's
possible at least for all container types in the library?  (But I note
that if you think it /shouldn't/ be done, I won't expect you to show me
how.)

> Should the language allow adding
> ad-hoc interfaces to existing types. Yes, and this is possible in Ada in
> some very uncomfortable AKA cumbersome way, which is why "finding maximum"
> is not a worthy abstraction in Ada.

I suspected one might have to extend the interfaces.  If a simple
abstraction (maximise F over X) does not have a simple representation,
it's not going to be worth it.  Just write a slightly different empty
test and loop each time you need to do it.

>>>> A fix (though it's not really ideal) would be to use function
>>>> composition here (inventing . as the composition operator):
>>>>     Map_Functions.Maximum_At (X.First, X.Last, Period'Access
>>>> . Element'Access)
>>>> but I don't think Ada has a function composition operator, does it?
>>>
>>> No as it would require closures.
>> What closure is required for a function composition?  There is no
>> environment to "close over".
>
> In Ada a function can use anything visible at its declaration point and at
> the location of its body. You can even declare a function inside a
> recursively called function and let it see local variables of each
> recursive call, in effect having an infinite set of functions.

At the point where I want Period.Element I can write the (almost)
one-line function that takes a Cursor and returns Period(Element(C))
entirely mechanically.  Can't the compiler do that?

Note I'm not asking if it /should/ (it may not be "Ada-like" to do
that).  I'm just curious if there really is a technical reason it can't
be done.

>> That's a lot just to use something that is supposed to be reusable.
>
> [rant on]
> An Ada programmer would just write a loop.

Yes, that's fine.  Different languages have different objectives.  Just
write the empty range test and the loop you need for each kind of
collection.  That was definitely the way things were done in the 80s.

>> It only occurred to me after writing the non-generic solution.  I
>> remember Ada as being something of a pioneer in it's attempt to provide
>> generic solutions, so I wondered how far things had come.  I don't think
>> something really widely reusable is possible in this case.
>
> As I said you think in a wrong direction of abstracting the language
> "finding maximum" rather than the problem space, e.g. generalization to
> other bases, other mathematical structures etc.

Generalising to an arbitrary base is local to the function that finds
the answer for one element.  It's an entirely separate axis of
generalisation to that of where the elements come from.

It's interesting to me that you consider one simply wrong and the other
natural.  In some languages the "wrong" one does not even merit
consideration as it's just there for free.  You can concentrate on the
other bases and other structures without worrying if the program will be
able to maximise over the collection in which they are stored.  (For
example, for polynomial residues, they can't come from a range like
2..999.)

I really do appreciate your help.  I would not have got off the ground
with generics without your examples.  Also, one thing I like about
Usenet is coming across people with very different ideas about
programming.  In this case, it seems to be about what is worth
generalising and what isn't.

-- 
Ben.

^ permalink raw reply	[relevance 0%]

* Re: project euler 26
  2023-09-08  1:32  0%                                 ` Ben Bacarisse
@ 2023-09-08  7:23  0%                                   ` Dmitry A. Kazakov
  2023-09-09  0:25  0%                                     ` Ben Bacarisse
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2023-09-08  7:23 UTC (permalink / raw)


On 2023-09-08 03:32, Ben Bacarisse wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On 2023-09-07 01:32, Ben Bacarisse wrote:
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>
>>>> On 2023-09-06 17:16, Ben Bacarisse wrote:
>>>>
>>> Second, if I try to use a Vector rather than an Ordered_Map, I am told
>>> that:
>>> test2.adb:97:05: error: instantiation error at line 12
>>> test2.adb:97:05: error: no visible subprogram matches the specification for "<"
>>> It would seem that vector cursors can't be compared using < (at least by
>>> default).  Maybe the installation needs more arguments.
>>
>> Vector has a proper index type. All you have to do is. Given
>>
>>     package Integer_Vectors is
>>        new Ada.Containers.Vectors (Integer, Integer);
>>
>> Wrap Element into a function:
>>
>>     V : Integer_Vectors.Vector;
>>     function Element (Index : Integer) return Integer is
>>     begin
>>        return V.Element (Index);
>>     end Element;
>>     ...
>>
>> and use the wrapper.
> 
> Sure, but the hope was to write something that does not need new
> code for new situations.  That's what makes it reusable.

Why should it be? You wanted to find maximum of a function. Vector is 
not a function. It is in mathematical terms, but not in the language 
terms. The abstraction for finding maximum in a container is just a 
different abstraction.

>> Then you would pass Has_Element for it. For integers you would use wrapped
>> X'Valid (there is no Integer'Valid, unfortunately. Only X'Valid where X is
>> an object).
> 
> It's definitely getting what I call cumbersome.

Yes, because you try too hard to make it work where it probably should not.

> I don't think this is incoherent.  The Haskell libraries ensure that any
> collection that is logically foldable is indeed foldable.

Ada arrays and library containers do not share interfaces. [It is a long 
discussion how they could be]. But similarly, there is no shared 
interface between digits of a number in octal base and a container and a 
string in UTF-16 encoding. Should there be? No. Should the language 
allow adding ad-hoc interfaces to existing types. Yes, and this is 
possible in Ada in some very uncomfortable AKA cumbersome way, which is 
why "finding maximum" is not a worthy abstraction in Ada.

>>> The bottom line is the last argument should be something very general
>>> like the Period function.
>>> A fix (though it's not really ideal) would be to use function
>>> composition here (inventing . as the composition operator):
>>>     Map_Functions.Maximum_At (X.First, X.Last, Period'Access
>>> . Element'Access)
>>> but I don't think Ada has a function composition operator, does it?
>>
>> No as it would require closures.
> 
> What closure is required for a function composition?  There is no
> environment to "close over".

In Ada a function can use anything visible at its declaration point and 
at the location of its body. You can even declare a function inside a 
recursively called function and let it see local variables of each 
recursive call, in effect having an infinite set of functions.

> That's a lot just to use something that is supposed to be reusable.

[rant on]
An Ada programmer would just write a loop. Abstractions are meant to 
abstract the problem domain. If you starting abstract elementary 
programming activities, then there might be something wrong with the 
language or with you.

Then there is a point about readability. When I see a loop I say, aha 
this is what the guy is going to do. When I see a pile of calls of a 
dozen generic instances with arbitrary names, I begin to worry.

In my view it is a road to nowhere, for an imperative language at least. 
The end of this road can be seen in modern C++. 20 years ago C++ was 
severely crippled broken but sometimes enjoyable language. You could 
*read* a C++ program. In these days with all libraries it became Forth 
on steroids. There is no such thing as a C++ program anymore, just calls 
upon calls.
[rant off]

> It only occurred to me after writing the non-generic solution.  I
> remember Ada as being something of a pioneer in it's attempt to provide
> generic solutions, so I wondered how far things had come.  I don't think
> something really widely reusable is possible in this case.

As I said you think in a wrong direction of abstracting the language 
"finding maximum" rather than the problem space, e.g. generalization to 
other bases, other mathematical structures etc.

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

^ permalink raw reply	[relevance 0%]

* Re: project euler 26
  2023-09-07  9:02  7%                               ` Dmitry A. Kazakov
@ 2023-09-08  1:32  0%                                 ` Ben Bacarisse
  2023-09-08  7:23  0%                                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Ben Bacarisse @ 2023-09-08  1:32 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On 2023-09-07 01:32, Ben Bacarisse wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>> On 2023-09-06 17:16, Ben Bacarisse wrote:
>>>
>>>> I am curious to know how reusable this is.  Can the packages be
>>>> instantiated in such a way that the argument ranges over the elements
>>>> of, say, and Ordered_Map?
>>>
>>> Sure:
>>>
>>>     with Ada.Containers.Ordered_Maps;
>>>
>>>     package Integer_Maps is
>>>        new Ada.Containers.Ordered_Maps (Integer, Integer);
>>>     use Integer_Maps;
>>>     package Cursor_Arguments is new Generic_Arguments (Cursor);
>> Ah!  So the arguments correspond to the "with" functions in the order
>> listed, and, since Cursor already has Next, there no need to specify
>> anything.
>
> Yes, because the formal argument is
>
>    with function Next (Value : Argument_Type)
>       return Argument_Type is <>;
>
> If it were
>
>    with function Next (Value : Argument_Type)
>       return Argument_Type;
>
> You would have to specify the actual. The part "is <>" tells to match a
> visible function Next.

Thanks.  I remember that now.  Given Ada's preference for words, it's a
mysterious choice.

>> There are a couple of details that prevent your Maximum_At function from
>> working properly in this case though.  First, we can't have an empty
>> map, because X.Last can't be compared with X.First when either is
>> No_Element, so the test for Right < Left fails before the desired error
>> can be raised.
>
> Yes, cursors is bad idea, in the end they all are pointers. No_Element is
> an equivalent of null which shows.
>
> However Maximum_At will propagate Constraint_Error if either of the bounds
> is No_Element. So the implementation would work.

Sure, but ideally we want the error we decided on for this situation.
Since the intent is to be generic, it's a shame to get one error with
some instantiations and a different one with others.

>> Second, if I try to use a Vector rather than an Ordered_Map, I am told
>> that:
>> test2.adb:97:05: error: instantiation error at line 12
>> test2.adb:97:05: error: no visible subprogram matches the specification for "<"
>> It would seem that vector cursors can't be compared using < (at least by
>> default).  Maybe the installation needs more arguments.
>
> Vector has a proper index type. All you have to do is. Given
>
>    package Integer_Vectors is
>       new Ada.Containers.Vectors (Integer, Integer);
>
> Wrap Element into a function:
>
>    V : Integer_Vectors.Vector;
>    function Element (Index : Integer) return Integer is
>    begin
>       return V.Element (Index);
>    end Element;
>    ...
>
> and use the wrapper.

Sure, but the hope was to write something that does not need new
code for new situations.  That's what makes it reusable.

>> Anyway, I am still not sure how to write a generic test for an empty
>> range.
>
> The problem is that the implementation of Cursor that breaks
> abstraction. The abstraction of an argument does not permit ideal
> non-values. Cursors and pointers have non-values. So if you want to test
> for non-values ahead, instead of surprising the function, you need to add a
> test for value validity to the abstraction:
>
> generic
>    -- Ordered argument
>    type Argument_Type is private;
>    with function Valid (Value : Argument_Type) return Boolean is <>;
>    ...
> package Generic_Arguments is
>
> Then you would pass Has_Element for it. For integers you would use wrapped
> X'Valid (there is no Integer'Valid, unfortunately. Only X'Valid where X is
> an object).

It's definitely getting what I call cumbersome.

>> It's possible I was not clear about what I was aiming for.  I was hoping
>> to be able to find the maximum of some arbitrary function, taking the
>> function's arguments from any sequential collection.
>
> That is a different abstraction. You need a generic collection instead of
> generic ordered values. E.g.
>
> generic
>    with package Arguments is new Ada.Containers.Ordered_Sets (<>);
>    with package Values is new Generic_Values (<>);
> package Generic_Comparable_Valued is
>    use Arguments, Values;
>    function Maximum_At
>             (  Domain : Set;
>                Func : access function (Argument : Element_Type)
>                       return Value_Type
>             )  return Value_Type;
>    -- Other useless functions
> end Generic_Comparable_Valued;
>
> package body Generic_Comparable_Valued is
>    function Maximum_At
>             (  Domain : Set;
>                Func : access function (Argument : Element_Type)
>                       return Value_Type
>             )  return Value_Type is
>       Max      : Value_Type;
>       Value    : Value_Type;
>       Position : Cursor;
>    begin
>       if Domain.Is_Empty then
>          raise Constraint_Error with "Empty set";
>       end if;
>       Position := Domain.First;
>       Max := Func (Element (Position));
>       while Position /= Domain.Last loop
>          Position := Next (Position);
>          Value := Func (Element (Position));
>          if Max < Value then
>             Max := Value;
>          end if;
>       end loop;
>       return Max;
>    end Maximum_At;
> end Generic_Comparable_Valued;
>
>> Either a simple
>> range of values, an array or vector of values, a list of values or even
>> an ordered map of values -- any ordered list of values.
>
> In practice such abstraction have too much physical and mental
> overhead. E.g. large sets of values implemented differently from
> Ada.Containers.Ordered_Sets depending on the operations required. For
> example, let you need a set complement? Usually programmers simply stick
> with software patterns instead. Too much reliance of libraries make
> programs incoherent.

The core of my Haskell solution is just a function decimalRepeatLength
that returns the repeat length given a divisor.  But once I'd got the
answer (by applying it to 2 to 999 and getting the maximum) I wondered
what would happen if the numbers were not in a simple range.  Is it easy
to write a `maximisedOver` function that finds the maximum of some
function over any ordered collection (technically, a "foldable" type in
Haskell).

Well, yes, it is easy:

  function `maximisedOver` anything = maximum (fmap function anything)

so the solution to the project Euler problem is just

  decimalRepeatLength `maximisedOver` [2..999]

but I can also find the maximum of this (or any other suitable) function
over an array, a hash map, a vector... whatever.  No code changes
anywhere.  It even works with arrays of any number of dimensions
regardless of the index bounds.

maximisedOver is genuinely generic and reusable.

I don't think this is incoherent.  The Haskell libraries ensure that any
collection that is logically foldable is indeed foldable.

>> The bottom line is the last argument should be something very general
>> like the Period function.
>> A fix (though it's not really ideal) would be to use function
>> composition here (inventing . as the composition operator):
>>    Map_Functions.Maximum_At (X.First, X.Last, Period'Access
>> . Element'Access)
>> but I don't think Ada has a function composition operator, does it?
>
> No as it would require closures.

What closure is required for a function composition?  There is no
environment to "close over".

> So you can have a generic composition
> operator, no problem, but not a first-class one. However you can simply add
> Maximum_At with four arguments to the package.

This may be the closest we can get with Ada.

>> Another solution would be to write Maximum_At so that it knows it has a
>> cursor argument, but then I don't think it would work for native arrays,
>> would it?  And we'd loose plain ranges altogether.
>
> You can write a generic package creating array cursors:
>
> generic
>    type Index_Type is (<>);
>    type Element_Type is private;
>    type Array_Type is array (Index_Type range <>) of Element_Type;
> package Array_Cursors is
>    type Cursor is private;
>    function First (Container : Array_Type) return Cursor;
>    function Element (Position : Cursor) return Element_Type;
>    function "<" (Left, Right : Cursor) return Boolean;
>    ...
> private
>    package Dirty_Tricks is
>       new System.Address_To_Access_Conversions (Array_Type);
>    use Dirty_Tricks;
>    type Cursor is record
>       Domain : Object_Pointer;
>       Index  : Index_Type;
>    end record;
> end Array_Cursors;
>
> package body Array_Cursors is
>    function "<" (Left, Right : Cursor) return Boolean is
>    begin
>       if Left.Domain = null or else Left.Domain /= Right.Domain then
>          raise Constraint_Error with "Incomparable cursors";
>       end if;
>       return Left.Index < Right.Index;
>    end "<";
>
>    function Element (Position : Cursor) return Element_Type is
>    begin
>       if Position.Domain = null or else
>          Position.Index not in Position.Domain'Range
>       then
>          raise Constraint_Error with "Invalid cursor";
>       else
>          return Position.Domain (Position.Index);
>       end if;
>    end Element;
>
>    function First (Container : Array_Type) return Cursor is
>    begin
>       if Container'Length = 0 then
>          raise Constraint_Error with "Empty array";
>       else
>          return (To_Pointer (Container'Address), Container'First);
>       end if;
>    end First;
>
> end Array_Cursors;

That's a lot just to use something that is supposed to be reusable.

>> You seem to be on your own as far as helping out is concerned!
>
> Because it started as a numeric puzzle. You should have asked directly
> about generics or tagged types instead.

It only occurred to me after writing the non-generic solution.  I
remember Ada as being something of a pioneer in it's attempt to provide
generic solutions, so I wondered how far things had come.  I don't think
something really widely reusable is possible in this case.

-- 
Ben.

^ permalink raw reply	[relevance 0%]

* Re: project euler 26
  2023-09-06 23:32  0%                             ` Ben Bacarisse
@ 2023-09-07  9:02  7%                               ` Dmitry A. Kazakov
  2023-09-08  1:32  0%                                 ` Ben Bacarisse
    1 sibling, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2023-09-07  9:02 UTC (permalink / raw)


On 2023-09-07 01:32, Ben Bacarisse wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On 2023-09-06 17:16, Ben Bacarisse wrote:
>>
>>> I am curious to know how reusable this is.  Can the packages be
>>> instantiated in such a way that the argument ranges over the elements
>>> of, say, and Ordered_Map?
>>
>> Sure:
>>
>>     with Ada.Containers.Ordered_Maps;
>>
>>     package Integer_Maps is
>>        new Ada.Containers.Ordered_Maps (Integer, Integer);
>>     use Integer_Maps;
>>     package Cursor_Arguments is new Generic_Arguments (Cursor);
> 
> Ah!  So the arguments correspond to the "with" functions in the order
> listed, and, since Cursor already has Next, there no need to specify
> anything.

Yes, because the formal argument is

    with function Next (Value : Argument_Type)
       return Argument_Type is <>;

If it were

    with function Next (Value : Argument_Type)
       return Argument_Type;

You would have to specify the actual. The part "is <>" tells to match a 
visible function Next.

> There are a couple of details that prevent your Maximum_At function from
> working properly in this case though.  First, we can't have an empty
> map, because X.Last can't be compared with X.First when either is
> No_Element, so the test for Right < Left fails before the desired error
> can be raised.

Yes, cursors is bad idea, in the end they all are pointers. No_Element 
is an equivalent of null which shows.

However Maximum_At will propagate Constraint_Error if either of the 
bounds is No_Element. So the implementation would work.

> Second, if I try to use a Vector rather than an Ordered_Map, I am told
> that:
> 
> test2.adb:97:05: error: instantiation error at line 12
> test2.adb:97:05: error: no visible subprogram matches the specification for "<"
> 
> It would seem that vector cursors can't be compared using < (at least by
> default).  Maybe the installation needs more arguments.

Vector has a proper index type. All you have to do is. Given

    package Integer_Vectors is
       new Ada.Containers.Vectors (Integer, Integer);

Wrap Element into a function:

    V : Integer_Vectors.Vector;
    function Element (Index : Integer) return Integer is
    begin
       return V.Element (Index);
    end Element;
    ...

and use the wrapper.

> Anyway, I am still not sure how to write a generic test for an empty
> range.

The problem is that the implementation of Cursor that breaks 
abstraction. The abstraction of an argument does not permit ideal 
non-values. Cursors and pointers have non-values. So if you want to test 
for non-values ahead, instead of surprising the function, you need to 
add a test for value validity to the abstraction:

generic
    -- Ordered argument
    type Argument_Type is private;
    with function Valid (Value : Argument_Type) return Boolean is <>;
    ...
package Generic_Arguments is

Then you would pass Has_Element for it. For integers you would use 
wrapped X'Valid (there is no Integer'Valid, unfortunately. Only X'Valid 
where X is an object).

> It's possible I was not clear about what I was aiming for.  I was hoping
> to be able to find the maximum of some arbitrary function, taking the
> function's arguments from any sequential collection.

That is a different abstraction. You need a generic collection instead 
of generic ordered values. E.g.

generic
    with package Arguments is new Ada.Containers.Ordered_Sets (<>);
    with package Values is new Generic_Values (<>);
package Generic_Comparable_Valued is
    use Arguments, Values;
    function Maximum_At
             (  Domain : Set;
                Func : access function (Argument : Element_Type)
                       return Value_Type
             )  return Value_Type;
    -- Other useless functions
end Generic_Comparable_Valued;

package body Generic_Comparable_Valued is
    function Maximum_At
             (  Domain : Set;
                Func : access function (Argument : Element_Type)
                       return Value_Type
             )  return Value_Type is
       Max      : Value_Type;
       Value    : Value_Type;
       Position : Cursor;
    begin
       if Domain.Is_Empty then
          raise Constraint_Error with "Empty set";
       end if;
       Position := Domain.First;
       Max := Func (Element (Position));
       while Position /= Domain.Last loop
          Position := Next (Position);
          Value := Func (Element (Position));
          if Max < Value then
             Max := Value;
          end if;
       end loop;
       return Max;
    end Maximum_At;
end Generic_Comparable_Valued;

> Either a simple
> range of values, an array or vector of values, a list of values or even
> an ordered map of values -- any ordered list of values.

In practice such abstraction have too much physical and mental overhead. 
E.g. large sets of values implemented differently from 
Ada.Containers.Ordered_Sets depending on the operations required. For 
example, let you need a set complement? Usually programmers simply stick 
with software patterns instead. Too much reliance of libraries make 
programs incoherent.

> The bottom line is the last argument should be something very general
> like the Period function.
> 
> A fix (though it's not really ideal) would be to use function
> composition here (inventing . as the composition operator):
> 
>    Map_Functions.Maximum_At (X.First, X.Last, Period'Access . Element'Access)
> 
> but I don't think Ada has a function composition operator, does it?

No as it would require closures. So you can have a generic composition 
operator, no problem, but not a first-class one. However you can simply 
add Maximum_At with four arguments to the package.

> Another solution would be to write Maximum_At so that it knows it has a
> cursor argument, but then I don't think it would work for native arrays,
> would it?  And we'd loose plain ranges altogether.

You can write a generic package creating array cursors:

generic
    type Index_Type is (<>);
    type Element_Type is private;
    type Array_Type is array (Index_Type range <>) of Element_Type;
package Array_Cursors is
    type Cursor is private;
    function First (Container : Array_Type) return Cursor;
    function Element (Position : Cursor) return Element_Type;
    function "<" (Left, Right : Cursor) return Boolean;
    ...
private
    package Dirty_Tricks is
       new System.Address_To_Access_Conversions (Array_Type);
    use Dirty_Tricks;
    type Cursor is record
       Domain : Object_Pointer;
       Index  : Index_Type;
    end record;
end Array_Cursors;

package body Array_Cursors is
    function "<" (Left, Right : Cursor) return Boolean is
    begin
       if Left.Domain = null or else Left.Domain /= Right.Domain then
          raise Constraint_Error with "Incomparable cursors";
       end if;
       return Left.Index < Right.Index;
    end "<";

    function Element (Position : Cursor) return Element_Type is
    begin
       if Position.Domain = null or else
          Position.Index not in Position.Domain'Range
       then
          raise Constraint_Error with "Invalid cursor";
       else
          return Position.Domain (Position.Index);
       end if;
    end Element;

    function First (Container : Array_Type) return Cursor is
    begin
       if Container'Length = 0 then
          raise Constraint_Error with "Empty array";
       else
          return (To_Pointer (Container'Address), Container'First);
       end if;
    end First;

end Array_Cursors;

> But then (I think) the only function one could pass would be something
> like Element as in you example above.  Using an ordered set of integers
> would not allow
> 
>    Map_Functions.Maximum_At (Set.First, Set.Last, Period'Access)
> 
> would it?

Ordered_Set cursors are ordered like Ordered_Map ones, so it should work.

>>> I am asking you but I am also the group.  I appreciate your help,
>>> but don't want you to feel any obligation to keep helping!
>>
>> No problem.
> 
> You seem to be on your own as far as helping out is concerned!

Because it started as a numeric puzzle. You should have asked directly 
about generics or tagged types instead.

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

^ permalink raw reply	[relevance 7%]

* Re: project euler 26
  2023-09-06 15:54  9%                           ` Dmitry A. Kazakov
@ 2023-09-06 23:32  0%                             ` Ben Bacarisse
  2023-09-07  9:02  7%                               ` Dmitry A. Kazakov
    0 siblings, 2 replies; 200+ results
From: Ben Bacarisse @ 2023-09-06 23:32 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On 2023-09-06 17:16, Ben Bacarisse wrote:
>
>> I am curious to know how reusable this is.  Can the packages be
>> instantiated in such a way that the argument ranges over the elements
>> of, say, and Ordered_Map?
>
> Sure:
>
>    with Ada.Containers.Ordered_Maps;
>
>    package Integer_Maps is
>       new Ada.Containers.Ordered_Maps (Integer, Integer);
>    use Integer_Maps;
>    package Cursor_Arguments is new Generic_Arguments (Cursor);

Ah!  So the arguments correspond to the "with" functions in the order
listed, and, since Cursor already has Next, there no need to specify
anything.  One could (I've just tried) use => notation.  You could have
written

  package Arguments is new Generic_Arguments (Next => Positive'Succ,
                                             Argument_Type => Positive);

in your first example -- swapping the order just to make the point
obvious.  This tripped me up when I was playing around with a Cursors
solution.

There are a couple of details that prevent your Maximum_At function from
working properly in this case though.  First, we can't have an empty
map, because X.Last can't be compared with X.First when either is
No_Element, so the test for Right < Left fails before the desired error
can be raised.

Second, if I try to use a Vector rather than an Ordered_Map, I am told
that:

test2.adb:97:05: error: instantiation error at line 12
test2.adb:97:05: error: no visible subprogram matches the specification for "<"

It would seem that vector cursors can't be compared using < (at least by
default).  Maybe the installation needs more arguments.

Anyway, I am still not sure how to write a generic test for an empty
range.

>    package Map_Values is new Generic_Values (Integer);
>    package Map_Functions is
>       new Generic_Discrete_Comparable_Valued
>           (Cursor_Arguments, Map_Values);
>
> Then given X is a map: X : Map;
>
>    Map_Functions.Maximum_At (X.First, X.Last, Element'Access)

It's possible I was not clear about what I was aiming for.  I was hoping
to be able to find the maximum of some arbitrary function, taking the
function's arguments from any sequential collection.  Either a simple
range of values, an array or vector of values, a list of values or even
an ordered map of values -- any ordered list of values.

The bottom line is the last argument should be something very general
like the Period function.

A fix (though it's not really ideal) would be to use function
composition here (inventing . as the composition operator):

  Map_Functions.Maximum_At (X.First, X.Last, Period'Access . Element'Access)

but I don't think Ada has a function composition operator, does it?

Another solution would be to write Maximum_At so that it knows it has a
cursor argument, but then I don't think it would work for native arrays,
would it?  And we'd loose plain ranges altogether.

>> Maybe a more generic a solution would involve passing something that can
>> be iterated over, rather than two values of an "enumerated" type?  I
>> mean enumerated in the mathematical sense -- it may be the wrong word in
>> Ada.
>
> Yes, but Ada does not have built-in range types. Therefore such design will
> not work out of the box with discrete types because 2..999 is not a proper
> object in Ada. However, talking about abstractions, you can create an
> interval type for the purpose or else use an ordered set of integers.

But then (I think) the only function one could pass would be something
like Element as in you example above.  Using an ordered set of integers
would not allow

  Map_Functions.Maximum_At (Set.First, Set.Last, Period'Access)

would it?

>> I am asking you but I am also the group.  I appreciate your help,
>> but don't want you to feel any obligation to keep helping!
>
> No problem.

You seem to be on your own as far as helping out is concerned!

-- 
Ben.

^ permalink raw reply	[relevance 0%]

* Re: project euler 26
  @ 2023-09-06 15:54  9%                           ` Dmitry A. Kazakov
  2023-09-06 23:32  0%                             ` Ben Bacarisse
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2023-09-06 15:54 UTC (permalink / raw)


On 2023-09-06 17:16, Ben Bacarisse wrote:

> I am curious to know how reusable this is.  Can the packages be
> instantiated in such a way that the argument ranges over the elements
> of, say, and Ordered_Map?

Sure:

    with Ada.Containers.Ordered_Maps;

    package Integer_Maps is
       new Ada.Containers.Ordered_Maps (Integer, Integer);
    use Integer_Maps;
    package Cursor_Arguments is new Generic_Arguments (Cursor);
    package Map_Values is new Generic_Values (Integer);
    package Map_Functions is
       new Generic_Discrete_Comparable_Valued
           (Cursor_Arguments, Map_Values);

Then given X is a map: X : Map;

    Map_Functions.Maximum_At (X.First, X.Last, Element'Access)

> Maybe a more generic a solution would involve passing something that can
> be iterated over, rather than two values of an "enumerated" type?  I
> mean enumerated in the mathematical sense -- it may be the wrong word in
> Ada.

Yes, but Ada does not have built-in range types. Therefore such design 
will not work out of the box with discrete types because 2..999 is not a 
proper object in Ada. However, talking about abstractions, you can 
create an interval type for the purpose or else use an ordered set of 
integers.

> I am asking you but I am also the group.  I appreciate your help,
> but don't want you to feel any obligation to keep helping!

No problem.

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

^ permalink raw reply	[relevance 9%]

* Re: project euler 26
  2023-09-05  7:23  0%               ` Dmitry A. Kazakov
  2023-09-05 15:18  0%                 ` Ben Bacarisse
@ 2023-09-05 17:35  0%                 ` moi
  1 sibling, 0 replies; 200+ results
From: moi @ 2023-09-05 17:35 UTC (permalink / raw)


On 05/09/2023 08:23, Dmitry A. Kazakov wrote:
> On 2023-09-05 01:16, Ben Bacarisse wrote:
> 
>> The term "abstraction" is usually taken to be more general than that so
>> as to include function (or procedural) abstraction.
> 
> These are means of software decomposition rather than abstraction (of 
> something).

They are both of these things, actually.

>
>> Ada is good at that, but the syntax is sufficiently cumbersome that I
>> think it discourages people from exploiting that part of the language.
>> Mind you, I am no Ada expert so maybe it's simpler to do than I think.
> 
> If the program does not resemble electric transmission noise, some 
> people call the language syntax cumbersome... (:-))

8-)

>> Here's my Ada solution:
>>
>> with Ada.Text_IO; use Ada.Text_IO;
>> with Ada.Containers.Ordered_Maps; use Ada.Containers;
>>
>> procedure Euler_26 is
>>
>>     function Period(Divisor: Positive) return Positive is
> 
> You cannot use a number here because the period may have leading zeros.
> 
>> I know it won't make this program shorter, but it would be interesting
>> to know how it might be done.
> 
> The goal of engineering is not making programs shorter, it is to make 
> them understandable, safer, reusable, maintainable, extensible, integrable.

Hear, hear!

Functionalists do seem to have an obsession with brevity at all costs.
It's very strange.

-- 
Bill F.

^ permalink raw reply	[relevance 0%]

* Re: project euler 26
  2023-09-05  7:23  0%               ` Dmitry A. Kazakov
@ 2023-09-05 15:18  0%                 ` Ben Bacarisse
    2023-09-05 17:35  0%                 ` moi
  1 sibling, 1 reply; 200+ results
From: Ben Bacarisse @ 2023-09-05 15:18 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On 2023-09-05 01:16, Ben Bacarisse wrote:
>
>> The term "abstraction" is usually taken to be more general than that so
>> as to include function (or procedural) abstraction.
>
> These are means of software decomposition rather than abstraction (of
> something).

That's not how the word is usually used.  Obviously I can't (and don't
want to) change your mind, but algorithms can be abstracted as well as
data.

I was hoping someone could how me how in for the example program I gave
since that's an area of Ada I am not familiar with (but I's sure it's
possible).

>> Ada is good at that, but the syntax is sufficiently cumbersome that I
>> think it discourages people from exploiting that part of the language.
>> Mind you, I am no Ada expert so maybe it's simpler to do than I think.
>
> If the program does not resemble electric transmission noise, some people
> call the language syntax cumbersome... (:-))

That's true.  But there are also constructs that are genuinely
cumbersome in some languages.  Anyway, to find out more, I was hoping
someone would show me what it looks like in Ada -- I outlined what I
wanted to do after the code I posted.

>> Here's my Ada solution:
>> with Ada.Text_IO; use Ada.Text_IO;
>> with Ada.Containers.Ordered_Maps; use Ada.Containers;
>> procedure Euler_26 is
>>     function Period(Divisor: Positive) return Positive is
>
> You cannot use a number here because the period may have leading
> zeros.

The function returns the decimal period of 1/Divisor.  I don't believe
there is a bug, but if you think you've found one, I'd like to know
about it.

Of course there can be leading zeros, but my algorithm ignores the
digits and determines the period using the "carry" instead.

>> I know it won't make this program shorter, but it would be interesting
>> to know how it might be done.
>
> The goal of engineering is not making programs shorter, it is to make them
> understandable, safer, reusable, maintainable, extensible, integrable.

Yes.  That's exactly why I was asking for someone who knows Ada better
to show me how to write the reusable component I described.  There was
boiler plate code in my program that could be abstracted out into a
generic function (or package?) so that any function can be maximised
over some range or, better yet, any iterable type (if that's how Ada
does things).

Can someone here show me how?

-- 
Ben.

^ permalink raw reply	[relevance 0%]

* Re: project euler 26
  2023-09-04 23:16  8%             ` Ben Bacarisse
@ 2023-09-05  7:23  0%               ` Dmitry A. Kazakov
  2023-09-05 15:18  0%                 ` Ben Bacarisse
  2023-09-05 17:35  0%                 ` moi
  0 siblings, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2023-09-05  7:23 UTC (permalink / raw)


On 2023-09-05 01:16, Ben Bacarisse wrote:

> The term "abstraction" is usually taken to be more general than that so
> as to include function (or procedural) abstraction.

These are means of software decomposition rather than abstraction (of 
something).

> Ada is good at that, but the syntax is sufficiently cumbersome that I
> think it discourages people from exploiting that part of the language.
> Mind you, I am no Ada expert so maybe it's simpler to do than I think.

If the program does not resemble electric transmission noise, some 
people call the language syntax cumbersome... (:-))

> Here's my Ada solution:
> 
> with Ada.Text_IO; use Ada.Text_IO;
> with Ada.Containers.Ordered_Maps; use Ada.Containers;
> 
> procedure Euler_26 is
> 
>     function Period(Divisor: Positive) return Positive is

You cannot use a number here because the period may have leading zeros.

> I know it won't make this program shorter, but it would be interesting
> to know how it might be done.

The goal of engineering is not making programs shorter, it is to make 
them understandable, safer, reusable, maintainable, extensible, integrable.

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

^ permalink raw reply	[relevance 0%]

* Re: project euler 26
  @ 2023-09-04 23:16  8%             ` Ben Bacarisse
  2023-09-05  7:23  0%               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Ben Bacarisse @ 2023-09-04 23:16 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On 2023-09-04 22:18, Ben Bacarisse wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>> On 2023-09-04 18:01, Ben Bacarisse wrote:
>>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>>
>>>>> BTW, Ada is perfect for numeric algorithms no need to resort to functional
>>>>> mess... (:-))
>>>> Perfect?  That's a bold claim!
>>>
>>> Ada is a very improved descendant of Algol 60, which was designed to codify
>>> algorithms.
>> Yes, though I was respond to you narrower remark about being perfect for
>> numeric algorithms.
>
> Yes, Ada is.

:-)

>>> (rather than about for example building
>>> abstractions as in the case of OOP)
>>
>> That's interesting.  You don't consider using functions and procedures
>> (possibly higher-order ones) to be a way to build abstractions?
>
> No, they do not introduce new types and do not form some structure of their
> values. And "using" is not an abstraction anyway.

The term "abstraction" is usually taken to be more general than that so
as to include function (or procedural) abstraction.

Ada is good at that, but the syntax is sufficiently cumbersome that I
think it discourages people from exploiting that part of the language.
Mind you, I am no Ada expert so maybe it's simpler to do than I think.

Here's my Ada solution:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Ordered_Maps; use Ada.Containers;

procedure Euler_26 is

   function Period(Divisor: Positive) return Positive is
      Index: Natural := 0;
      Carry: Natural := 1;

      package Carry_Maps is new Ordered_Maps(Natural, Natural);
      use Carry_Maps;
      Carries: Map;
      Loc: Cursor;
   begin
      loop
          Loc := Carries.Find(Carry);
          exit when Loc /= No_Element;
          Carries.Insert(Carry, Index);
          Index := Index + 1;
          Carry := Carry mod Divisor * 10;
      end loop;
      return Index - Element(Loc);
   end Period;

   Max_Period: Natural := 1;
   Divisor_With_Max_Period: Natural := 1;
begin
   for D in 2..999 loop
      declare Ds_Period: constant Positive := Period(D);
      begin
         if Ds_Period > Max_Period
         then
            Divisor_With_Max_Period := D;
            Max_Period := Ds_Period;
         end if;
      end;
   end loop;
   Put_Line(Integer'Image(Divisor_With_Max_Period));
end Euler_26;

The part that finds the D that maximises Period(D) is just boilerplate
code.  I know this can be abstracted out in Ada, but I think the syntax
is messy.  I was hoping to find (or be able to write) a generic function
that takes an 'iterable' (if that's the right word) and a function, and
which returns the element that maximises the function.  I got stuck
trying.  Maybe someone can help?

I know it won't make this program shorter, but it would be interesting
to know how it might be done.

-- 
Ben.

^ permalink raw reply	[relevance 8%]

* Re: Formal Package Compiler Differences
  2023-07-14 19:17 10% Formal Package Compiler Differences Jeffrey R.Carter
@ 2023-07-14 19:27  0% ` Jeffrey R.Carter
  0 siblings, 0 replies; 200+ results
From: Jeffrey R.Carter @ 2023-07-14 19:27 UTC (permalink / raw)


On 2023-07-14 21:17, Jeffrey R.Carter wrote:
> I have a generic pkg;
> 
> with Ada.Containers.Vectors;
> 
> generic -- Vector_Conversions
>     type Index is range <>;
>     type Element is private;
>     type Fixed is array (Index range <>) of Element;
> 
>     with function "=" (Left : in Element; Right : in Element) return Boolean
>     is <>;

Oops! This "=" should be removed to get the behavior described.

> 
>     with package Unbounded is new Ada.Containers.Vectors
>        (Index_Type => Index, Element_Type => Element);
> package Vector_Conversions is
>     -- Empty
> end Vector_Conversions;
> 
> and an instantiation of
> 
> with Ada.Containers.Vectors;
> with Ada.Strings.Unbounded;
> with Vector_Conversions;
> 
> procedure Instance_Test is
>     use Ada.Strings.Unbounded;
> 
>     package String_Lists is new Ada.Containers.Vectors
>        (Index_Type => Positive, Element_Type => Unbounded_String);
> 
>     type String_List is array (Positive range <>) of Unbounded_String;
> 
>     package Conversions is new Vector_Conversions
>        (Index     => Positive,
>         Element   => Unbounded_String,
>         Fixed     => String_List,
>         Unbounded => String_Lists);
> begin -- Instance_Test
>     null;
> end Instance_Test;
> 
> Compiler G compiles this and it works fine.
> 
> Compiler O fails to compile the instantiation with the error msg "The subprogram 
> actuals for the formal package and actual package must statically denote the 
> same entity", pointing to the Unbounded parameter association and referencing 
> ARM 12.7(8). If I add an explicit "=" with "is <>" to Vector_Conversions, then 
> compiler O compiles it and it works fine.
> 
> Possibly one of the compilers has an error, but possibly they're both correct, 
> and I'm wondering if it's possible to tell which is the case.
> 
> (If anyone is interested, the actual generic pkg where I encountered this is 
> PragmARC.Conversions.Vectors from the PragmAda Reusable Components 
> [https://github.com/jrcarter/PragmARC]), and I will supply the actual code that 
> instantiates it on demand. What I've presented is a first attempt at a minimal 
> reproducer.)
> 

-- 
Jeff Carter
"Make sure your code 'does nothing' gracefully."
Elements of Programming Style
196

^ permalink raw reply	[relevance 0%]

* Formal Package Compiler Differences
@ 2023-07-14 19:17 10% Jeffrey R.Carter
  2023-07-14 19:27  0% ` Jeffrey R.Carter
  0 siblings, 1 reply; 200+ results
From: Jeffrey R.Carter @ 2023-07-14 19:17 UTC (permalink / raw)


I have a generic pkg;

with Ada.Containers.Vectors;

generic -- Vector_Conversions
    type Index is range <>;
    type Element is private;
    type Fixed is array (Index range <>) of Element;

    with function "=" (Left : in Element; Right : in Element) return Boolean
    is <>;

    with package Unbounded is new Ada.Containers.Vectors
       (Index_Type => Index, Element_Type => Element);
package Vector_Conversions is
    -- Empty
end Vector_Conversions;

and an instantiation of

with Ada.Containers.Vectors;
with Ada.Strings.Unbounded;
with Vector_Conversions;

procedure Instance_Test is
    use Ada.Strings.Unbounded;

    package String_Lists is new Ada.Containers.Vectors
       (Index_Type => Positive, Element_Type => Unbounded_String);

    type String_List is array (Positive range <>) of Unbounded_String;

    package Conversions is new Vector_Conversions
       (Index     => Positive,
        Element   => Unbounded_String,
        Fixed     => String_List,
        Unbounded => String_Lists);
begin -- Instance_Test
    null;
end Instance_Test;

Compiler G compiles this and it works fine.

Compiler O fails to compile the instantiation with the error msg "The subprogram 
actuals for the formal package and actual package must statically denote the 
same entity", pointing to the Unbounded parameter association and referencing 
ARM 12.7(8). If I add an explicit "=" with "is <>" to Vector_Conversions, then 
compiler O compiles it and it works fine.

Possibly one of the compilers has an error, but possibly they're both correct, 
and I'm wondering if it's possible to tell which is the case.

(If anyone is interested, the actual generic pkg where I encountered this is 
PragmARC.Conversions.Vectors from the PragmAda Reusable Components 
[https://github.com/jrcarter/PragmARC]), and I will supply the actual code that 
instantiates it on demand. What I've presented is a first attempt at a minimal 
reproducer.)

-- 
Jeff Carter
"Make sure your code 'does nothing' gracefully."
Elements of Programming Style
196

^ permalink raw reply	[relevance 10%]

* Re: Hi guys! I've been inactive for a long time but now started to develop a hobby application. I found a strange behaviour with gdb. Locally renaming a function S in order to shorten the source code visits cygwin.S during execution. thie is very awk
  @ 2023-04-18 11:18  6%       ` Petter
  0 siblings, 0 replies; 200+ results
From: Petter @ 2023-04-18 11:18 UTC (permalink / raw)


Thanks for the advice. But I could not find an easy way to start using another newsreader. Also, since I'm now retired. I'm not prepared to spend any more money. 

I'd be grateful if someone addressed to problem in the OP: why do i have to hit F7 so many times? I also found out that I might not want to step into Ada.Containers.Vectors which is visited a lot of times for just a simple "for I of Vector". And more, something periodically triggers an abort_signal caught by ACV causing more F7s.

(I semi-retired 2 years ago and fully last year from a career in consultancy. Some of you have seen my posts a few years ago, when I was at in order Nobel Tech, SAAB Ericsson Aerotronics, SAAB Dynamics. Randy might remember that I started my career at SAAB UNIVAC later to become UNISYS which Randy and friends created an ADA Compiler which I sadly never had a chance to try.)

^ permalink raw reply	[relevance 6%]

* Re: Ada and Unicode
  2023-03-31  3:06  6%               ` Thomas
@ 2023-04-01 10:18  0%                 ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2023-04-01 10:18 UTC (permalink / raw)


I'm not going to answer this point-by-point, as it would take very much too 
long, and there is a similar thread going on the ARG's Github (which needs 
my attention more than comp.lang.ada.

But my opinion is that Ada got strings completely wrong, and the best thing 
to do with them is to completely nuke them and start over. But one cannot do 
that in the context of Ada, one would have to at least leave way to use the 
old mechanisms for compatibility with older code. That would leave a 
hodge-podge of mechanisms that would make Ada very much harder (rather than 
easier) to use.

As far as the cruft goes, I wrote up a 20+ page document on that during the 
pandemic, but I could never interest anyone knowledgeable to review it, and 
I don't plan to make it available without that. Most of the things are 
caused by interactions -- mostly because of too much generality. And of 
course there are features that Ada would be better off without (like 
anonymous access types).

                          Randy.

"Thomas" <fantome.forums.tDeContes@free.fr.invalid> wrote in message 
news:64264e2f$0$25952$426a74cc@news.free.fr...
> In article <t2g0c1$eou$1@dont-email.me>,
> "Randy Brukardt" <randy@rrsoftware.com> wrote:
>
>> "Thomas" <fantome.forums.tDeContes@free.fr.invalid> wrote in message
>> news:fantome.forums.tDeContes-5E3B70.20370903042022@news.free.fr...
>> ...
>> > as i said to Vadim Godunko, i need to fill a string type with an UTF-8
>> > litteral.but i don't think this string type has to manage various
>> > conversions.
>> >
>> > from my point of view, each library has to accept 1 kind of string type
>> > (preferably UTF-8 everywhere),
>> > and then, this library has to make needed conversions regarding the
>> > underlying API. not the user.
>>
>> This certainly is a fine ivory tower solution,
>
> I like to think from an ivory tower,
> and then look at the reality to see what's possible to do or not. :-)
>
>
>
>> but it completely ignores two
>> practicalities in the case of Ada:
>>
>> (1) You need to replace almost all of the existing Ada language defined
>> packages to make this work. Things that are deeply embedded in both
>> implementations and programs (like Ada.Exceptions and Ada.Text_IO) would
>> have to change substantially. The result would essentially be a different
>> language, since the resulting libraries would not work with most existing
>> programs.
>
> - in Ada, of course we can't delete what's existing, and there are many
> packages which are already in 3 versions (S/WS/WWS).
> imho, it would be consistent to make a 4th version of them for a new
> UTF_8_String type.
>
> - in a new language close to Ada, it would not necessarily be a good
> idea to remove some of them, depending on industrial needs, to keep them
> with us.
>
>> They'd have to have different names (since if you used the same
>> names, you change the failures from compile-time to runtime -- or even
>> undetected -- which would be completely against the spirit of Ada), which
>> means that one would have to essentially start over learning and using 
>> the
>> resulting language.
>
> i think i don't understand.
>
>> (and it would make sense to use this point to
>> eliminate a lot of the cruft from the Ada design).
>
> could you give an example of cruft from the Ada design, please? :-)
>
>
>>
>> (2) One needs to be able to read and write data given whatever encoding 
>> the
>> project requires (that's often decided by outside forces, such as other
>> hardware or software that the project needs to interoperate with).
>
>> At a minimum, you
>> have to have a way to specify the encoding of files, streams, and 
>> hardware
>> interfaces
>
>> That will greatly complicate the interface and
>> implementation of the libraries.
>
> i don't think so.
> it's a matter of interfacing libraries, for the purpose of communicating
> with the outside (neither of internal libraries nor of the choice of the
> internal type for the implementation).
>
> Ada.Text_IO.Open.Form already allows (a part of?) this (on the content
> of the files, not on their name), see ARM A.10.2 (6-8).
> (write i the reference to ARM correctly?)
>
>
>
>>
>> > ... of course, it would be very nice to have a more thicker language 
>> > with
>> > a garbage collector ...
>>
>> I doubt that you will ever see that in the Ada family,
>
>> as analysis and
>> therefore determinism is a very important property for the language.
>
> I completely agree :-)
>
>> Ada has
>> lots of mechanisms for managing storage without directly doing it 
>> yourself
>> (by calling Unchecked_Deallocation), yet none of them use any garbage
>> collection in a traditional sense.
>
> sorry, i meant "garbage collector" in a generic sense, not in a
> traditional sense.
> that is, as Ada users we could program with pointers and pool, without
> memory leaks nor calling Unchecked_Deallocation.
>
> for example Ada.Containers.Indefinite_Holders.
>
> i already wrote one for constrained limited types.
> do you know if it's possible to do it for unconstrained limited types,
> like the class of a limited tagged type?
>
> -- 
> RAPID maintainer
> http://savannah.nongnu.org/projects/rapid/ 


^ permalink raw reply	[relevance 0%]

* Re: Ada and Unicode
  @ 2023-03-31  3:06  6%               ` Thomas
  2023-04-01 10:18  0%                 ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Thomas @ 2023-03-31  3:06 UTC (permalink / raw)


In article <t2g0c1$eou$1@dont-email.me>,
 "Randy Brukardt" <randy@rrsoftware.com> wrote:

> "Thomas" <fantome.forums.tDeContes@free.fr.invalid> wrote in message 
> news:fantome.forums.tDeContes-5E3B70.20370903042022@news.free.fr...
> ...
> > as i said to Vadim Godunko, i need to fill a string type with an UTF-8
> > litteral.but i don't think this string type has to manage various 
> > conversions.
> >
> > from my point of view, each library has to accept 1 kind of string type
> > (preferably UTF-8 everywhere),
> > and then, this library has to make needed conversions regarding the
> > underlying API. not the user.
> 
> This certainly is a fine ivory tower solution,

I like to think from an ivory tower, 
and then look at the reality to see what's possible to do or not. :-)



> but it completely ignores two 
> practicalities in the case of Ada:
> 
> (1) You need to replace almost all of the existing Ada language defined 
> packages to make this work. Things that are deeply embedded in both 
> implementations and programs (like Ada.Exceptions and Ada.Text_IO) would 
> have to change substantially. The result would essentially be a different 
> language, since the resulting libraries would not work with most existing 
> programs.

- in Ada, of course we can't delete what's existing, and there are many 
packages which are already in 3 versions (S/WS/WWS).
imho, it would be consistent to make a 4th version of them for a new 
UTF_8_String type.

- in a new language close to Ada, it would not necessarily be a good 
idea to remove some of them, depending on industrial needs, to keep them 
with us.

> They'd have to have different names (since if you used the same 
> names, you change the failures from compile-time to runtime -- or even 
> undetected -- which would be completely against the spirit of Ada), which 
> means that one would have to essentially start over learning and using the 
> resulting language.

i think i don't understand.

> (and it would make sense to use this point to 
> eliminate a lot of the cruft from the Ada design).

could you give an example of cruft from the Ada design, please? :-)


> 
> (2) One needs to be able to read and write data given whatever encoding the 
> project requires (that's often decided by outside forces, such as other 
> hardware or software that the project needs to interoperate with).

> At a minimum, you 
> have to have a way to specify the encoding of files, streams, and hardware 
> interfaces

> That will greatly complicate the interface and 
> implementation of the libraries.

i don't think so.
it's a matter of interfacing libraries, for the purpose of communicating 
with the outside (neither of internal libraries nor of the choice of the 
internal type for the implementation).

Ada.Text_IO.Open.Form already allows (a part of?) this (on the content 
of the files, not on their name), see ARM A.10.2 (6-8).
(write i the reference to ARM correctly?)



> 
> > ... of course, it would be very nice to have a more thicker language with 
> > a garbage collector ...
> 
> I doubt that you will ever see that in the Ada family,

> as analysis and 
> therefore determinism is a very important property for the language.

I completely agree :-)

> Ada has 
> lots of mechanisms for managing storage without directly doing it yourself 
> (by calling Unchecked_Deallocation), yet none of them use any garbage 
> collection in a traditional sense.

sorry, i meant "garbage collector" in a generic sense, not in a 
traditional sense.
that is, as Ada users we could program with pointers and pool, without 
memory leaks nor calling Unchecked_Deallocation.

for example Ada.Containers.Indefinite_Holders.

i already wrote one for constrained limited types.
do you know if it's possible to do it for unconstrained limited types, 
like the class of a limited tagged type?

-- 
RAPID maintainer
http://savannah.nongnu.org/projects/rapid/

^ permalink raw reply	[relevance 6%]

* Is this a compiler bug ?
@ 2023-03-19  6:17  7% Rod Kay
  0 siblings, 0 replies; 200+ results
From: Rod Kay @ 2023-03-19  6:17 UTC (permalink / raw)


Hi all,

    Came across this during a port of the Box2D physics engine.

    It's a generic Stack package using 'ada.Containers.Vectors' to 
implement the stack.

    One generic parameter is the 'initial_Capacity' of the stack, used 
in the 'to_Stack' construction function, via the Vectors 
'reserve_Capacity' procedure.

    In the 'to_Stack' function, the Capacity is reserved correctly but 
in the test program when the stack is created and assigned to a 
variable, the capacity is 0.

    Here is the (very small) source code ...

    https://gist.github.com/charlie5/7b4d863227a510f834c2bfd781dd50ba


    The output I get with GCC 12.2.0 is ...

[rod@orth bug]$ ./stack_bug
to_Stack ~ Initial Capacity: 256
to_Stack ~ Before reserve:   0
to_Stack ~ After reserve:    256
stack_Bug ~ Actual Capacity: 0


Regards.

^ permalink raw reply	[relevance 7%]

* Re: Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ?
  2023-02-14  8:49 19% Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ? reinert
  2023-02-14  9:35 11% ` Jeffrey R.Carter
  2023-03-15 10:05 12% ` Marius Amado-Alves
@ 2023-03-15 14:24 11% ` Brad Moore
  2 siblings, 0 replies; 200+ results
From: Brad Moore @ 2023-03-15 14:24 UTC (permalink / raw)


On Tuesday, February 14, 2023 at 1:49:55 AM UTC-7, reinert wrote:
> Hello, 
> , 
> Sometimes, I have to sort records. One possibility is to use Generig_Sorting under Ada.Containers.Vectors and eksplicitly use Sort. An alternative is to use Ada.Containders.Ordered_Sets and somehow get sorting "for free". 
> 
> I would like to get arguments for and against these two alternatives. 
> 
> reinert

I might use the generic sorting for example, for the case where the data is more static and needs to be sorted once, whereas I'd use an ordered set if the data is continuously being updated and manipulated, or if I needed set semantics.

Brad

^ permalink raw reply	[relevance 11%]

* Re: Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ?
  2023-02-14  8:49 19% Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ? reinert
  2023-02-14  9:35 11% ` Jeffrey R.Carter
@ 2023-03-15 10:05 12% ` Marius Amado-Alves
  2023-03-15 14:24 11% ` Brad Moore
  2 siblings, 0 replies; 200+ results
From: Marius Amado-Alves @ 2023-03-15 10:05 UTC (permalink / raw)


> Sometimes, I have to sort records. One possibility is to use Generig_Sorting under Ada.Containers.Vectors and eksplicitly use Sort. An alternative is to use Ada.Containders.Ordered_Sets and somehow get sorting "for free". 
> 
> I would like to get arguments for and against these two alternatives. 
> 
> reinert

Sets have slightly stricter semantics, namely no duplicates. Normally, if the real data has this semantics, you should use sets (and populate with Include or else catch the exception raised upon trying to Insert a duplicate).

^ permalink raw reply	[relevance 12%]

* Re: Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ?
  2023-02-14 10:46 12%   ` reinert
@ 2023-02-14 18:48 11%     ` G.B.
  0 siblings, 0 replies; 200+ results
From: G.B. @ 2023-02-14 18:48 UTC (permalink / raw)


On 14.02.23 11:46, reinert wrote:
> My main argument for using Ordered_Sets is that it seems to be less verbose and somehow garanteres sorting. Myset.Last/First always provides the "largest"/"smallest" element.

You could measure performance of operations
that you find critical, given a typical number
of elements in the set. If there isn't any operation
that is particularly critical, some weighted
average of all set operations might be of interest.

Two similar data structures might both use a common
algorithm, such as sorting. If a program uses both
data structures, then having just one algorithm
might be advantageous, if only for the size of
the executable.

^ permalink raw reply	[relevance 11%]

* Re: Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ?
  2023-02-14  9:35 11% ` Jeffrey R.Carter
@ 2023-02-14 10:46 12%   ` reinert
  2023-02-14 18:48 11%     ` G.B.
  0 siblings, 1 reply; 200+ results
From: reinert @ 2023-02-14 10:46 UTC (permalink / raw)


My main argument for using Ordered_Sets is that it seems to be less verbose and somehow garanteres sorting. Myset.Last/First always provides the "largest"/"smallest" element.

reinert



^ permalink raw reply	[relevance 12%]

* Re: Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ?
  2023-02-14  8:49 19% Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ? reinert
@ 2023-02-14  9:35 11% ` Jeffrey R.Carter
  2023-02-14 10:46 12%   ` reinert
  2023-03-15 10:05 12% ` Marius Amado-Alves
  2023-03-15 14:24 11% ` Brad Moore
  2 siblings, 1 reply; 200+ results
From: Jeffrey R.Carter @ 2023-02-14  9:35 UTC (permalink / raw)


On 2023-02-14 09:49, reinert wrote:
> 
> Sometimes, I have to sort records. One possibility is to use Generig_Sorting under Ada.Containers.Vectors and eksplicitly use Sort.  An alternative is to use Ada.Containders.Ordered_Sets and somehow get sorting "for free".
> 
> I would like to get arguments for and against these two alternatives.

Both should be O(NlogN), so the distinction is which works better for what you 
do with them after they are sorted.

-- 
Jeff Carter
"[B]ecause of our experience in security, we are convinced
that C is too error-prone. Its loose typing, its unsafe
bitfields management, too many compiler dependent behaviors,
etc. easily lead to vulnerabilities."
EwoK developers
163

^ permalink raw reply	[relevance 11%]

* Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ?
@ 2023-02-14  8:49 19% reinert
  2023-02-14  9:35 11% ` Jeffrey R.Carter
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: reinert @ 2023-02-14  8:49 UTC (permalink / raw)


Hello,

Sometimes, I have to sort records. One possibility is to use Generig_Sorting under Ada.Containers.Vectors and eksplicitly use Sort.  An alternative is to use Ada.Containders.Ordered_Sets and somehow get sorting "for free". 

I would like to get arguments for and against these two alternatives.

reinert

^ permalink raw reply	[relevance 19%]

* Re: Real_Arrays on heap with overloaded operators and clean syntax
  2023-01-26 21:52  5%   ` Jim Paloander
@ 2023-02-02 21:59  0%     ` Jerry
  0 siblings, 0 replies; 200+ results
From: Jerry @ 2023-02-02 21:59 UTC (permalink / raw)



> Thank you Jerry, that's true, this trick does the job indeed. Thanks. But to be honest among us, it seems to me that the Real_Arrays library has been implemented probably (note the probably) by people not targeting real world engineering / industrial applications. Examples are Finite Volume solutions of semiconductor device equations, or weather prediction problems. You cannot expect to solve these on the stack and of course ADA containers are impractical for such computations. Possibly a library as discussed above that provides Real_Arrays functionality but memory allocation is done internally on the heap or even on the stack if the user chooses to do so to take advantage of fast stack access. But then the mechanism for changing the stack allocation size transparently and easily should also be provided as simply as setting the memory pool in an access type. 
> 
> Do you agree? 
> 
Yes, with the minor caveat that I have no idea what I'm talking about.

When I ran into this limitation a few years ago, I learned how to increase the stack size before running my program. This helped but only a little, as large arrays still were not accommodated. (Define "large" as anything too big for stack expanded to OS limits.) I have never compared speed with stack versus heap allocation because, for me, it would serve no purpose. I can't just use smaller arrays in my work because large ones are too slow, if you follow my drift here.

The applications you mention are great but the list must be nearly endless. My applications run towards audio signals and radar (simulation) images.

Jerry

^ permalink raw reply	[relevance 0%]

* Re: Real_Arrays on heap with overloaded operators and clean syntax
  @ 2023-01-26 21:52  5%   ` Jim Paloander
  2023-02-02 21:59  0%     ` Jerry
  0 siblings, 1 reply; 200+ results
From: Jim Paloander @ 2023-01-26 21:52 UTC (permalink / raw)


> > Dear ADA lovers, 
> > with stack allocation of Real_Vector ( 1 .. N ) when N >= 100,000 I get STACK_OVERFLOW ERROR while trying to check how fast operator overloading is working for an expression
> Leo's answer is responsive to the OP but seems to have gotten buried in an amazingly long discussion which I haven't read. This answer appeared here years ago (was it you, Leo?) and I have used it ever since. If there needs to be a long discussion maybe it could be about why this workaround is necessary. I will pull out Leo's answer from his post and put my version here: 
> 
> type Real_Vector_Access is access Real_Vector; 
> then 
> x_Ptr : Real_Vector_Access := new Real_Vector(0 .. N - 1); 
> x : Real_Vector renames x_Ptr.all; 
> 
> That's all. All the overloaded operators work as though the vector was declared from the stack. If you have code which formerly used stack allocation (of x, in this example), it will work without modification with this trick. 
> 
> Jerry

Thank you Jerry, that's true, this trick does the job indeed. Thanks. But to be honest among us, it seems to me that the Real_Arrays library has been implemented probably (note the probably) by people not targeting real world engineering / industrial applications. Examples are Finite Volume solutions of semiconductor device equations, or weather prediction problems. You cannot expect to solve these on the stack and of course ADA containers are impractical for such computations. Possibly a library as discussed above that provides Real_Arrays functionality but memory allocation is done internally on the heap or even on the stack if the user chooses to do so to take advantage of fast stack access. But then the mechanism for changing the stack allocation size transparently and easily should also be provided as simply as setting the memory pool in an access type.

Do you agree? 

In the meantime, I am wondering whether or not a hybrid approach (stack/heap) would work provided such a mechanism to set the stack size is easy accessible as simply as a memory pool. The functionality would be during operator overloading we create fast stack allocated arrays to transfer the intermediate results stored in temporary objects. So all the temporaries described above would reside in the stack if this would translate to performance improvement until a smarter approach is introduced similar to C++ expression templates.

^ permalink raw reply	[relevance 5%]

* Re: Real_Arrays on heap with overloaded operators and clean syntax
  @ 2023-01-24 19:47  7% ` Gautier write-only address
    1 sibling, 0 replies; 200+ results
From: Gautier write-only address @ 2023-01-24 19:47 UTC (permalink / raw)


There are plenty of legitimate complaints and good ideas in this thread.

- need for a package for large matrices (issue with stack allocation)
- should support approximations (at least, floating-point) real and complex numbers (and perhaps others)
- should support various matrix storages: sparse storages, band storages, ...

Fortunately Ada (not "ADA" = "American Dentist Association" and some others...) is powerful enough to have such components written in Ada itself (with GNAT, it is done exactly like this).
So _we_ don't need to wait that _they_ do anything about it :-)

So, if I summarize the ideas discussed and combine with stuff grabbed from a toolbox of mine ( https://github.com/zertovitch/mathpaqs
 ), I obtain the following specification.
The choice between different kind of matrix storages would be trivial.
Comments are welcome!

---8<--------8<--------8<--------8<--------8<--------8<-----
--  Draft of a specification for an universal matrix package.

--  The elements of the vectors and matrices can be of any algebraic ring
--  and their implementation, eventually approximate:
--
--    - integers (stored as Integer, Integer_n or Big_Integer)
--    - modular integers
--    - real numbers (approximated as floating-point, fixed-point or Big_Real)
--    - complex numbers
--    - rational numbers
--    - polynomials (of real, complex, rational, ...)
--    - other matrices
--    - ...

with Ada.Containers.Vectors;

generic

  type Ring_Element is private;  --  Element of an algebraic ring

  zero, one : Ring_Element;                                     --  0 and 1 elements

  with function "-" (a : Ring_Element) return Ring_Element;     --  Unary operators

  with function "+" (a, b : Ring_Element) return Ring_Element;  --  Binary operators
  with function "-" (a, b : Ring_Element) return Ring_Element;
  with function "*" (a, b : Ring_Element) return Ring_Element;

package Universal_Matrices is

  package UM_Vectors is new Ada.Containers.Vectors (Positive, Ring_Element);

  subtype Vector is UM_Vectors.Vector;

  -------------------------
  --  Vector operations  --
  -------------------------

  function "*" (v : Vector; factor : Ring_Element) return Vector;
  function "*" (factor : Ring_Element; v : Vector) return Vector;

  --  v := factor * v :
  procedure Scale_Left (v : in out Vector; factor : Ring_Element);

  function "-" (v : Vector) return Vector;

  function "+" (v, w : Vector) return Vector;
  --  v := v + w :
  procedure Add (v : in out Vector; w : Vector);
  --  v := v + factor * w :
  procedure Add_Left_Scaled (v : in out Vector; factor : Ring_Element; w : Vector);

  function "-" (v, w : Vector) return Vector;
  --  v := v - w :
  procedure Subtract (v : in out Vector; w : Vector);

  function "*" (v, w : Vector) return Ring_Element;

  --  Euclidean norm and distance:
  function Square_L2_Norm (v : Vector) return Ring_Element;
  function Square_L2_Distance (v, w : Vector) return Ring_Element;

  -------------------------------------------------------------------
  --  Root matrix type.                                            --
  --  Possible derivations: dense, sparse, band storage matrices.  --
  -------------------------------------------------------------------

  type Matrix is interface;

  -------------------------
  --  Matrix operations  --
  -------------------------

  function Transpose (A : Matrix) return Matrix is abstract;
  function Identity (order : Positive) return Matrix is abstract;
  function "*" (factor : Ring_Element; A : Matrix) return Matrix is abstract;
  function "*" (A : Matrix; factor : Ring_Element) return Matrix is abstract;
  function "*" (A, B : Matrix) return Matrix is abstract;
  function "+" (A, B : Matrix) return Matrix is abstract;
  function "-" (A, B : Matrix) return Matrix is abstract;

  --  Matrix-Vector operations

  function "*" (A : Matrix; x : Vector) return Vector is abstract;

end Universal_Matrices;

^ permalink raw reply	[relevance 7%]

* Re: Graph database client? eg Neo4j, Dgraph ...
  2019-08-20 15:13  0%     ` Shark8
@ 2022-12-22 13:16  0%       ` Marius Amado-Alves
  0 siblings, 0 replies; 200+ results
From: Marius Amado-Alves @ 2022-12-22 13:16 UTC (permalink / raw)


> > > There is/was an all-Ada graph-DB called Mneson -- Archived here: https://web.archive.org/web/20070625173813/http://www.liacc.up.pt/~maa/mneson/ -- of which I have a copy of two versions. I was trying to translate them so that instead of the containers dependency ["Charles Containers", IIRC] they would use the Ada.Containers.* packages instead. 
> > 
> > Thx! I communicated with the author to bring this code on github. More to come.
> Did the code ever make it to github? 
> Did anything else ever happen here?

Yes, after 17 years in the refrigerator the code is now on github, including an adaptation to build on present GNAT:

https://github.com/marius-linguist/Mneson

^ permalink raw reply	[relevance 0%]

* Re: tokyocabinet,redis,mongodb,couchdb,influxdb,timescaledb connectors.
  2019-11-01 13:51  9% ` Shark8
  2019-11-01 14:39  0%   ` Alain De Vos
@ 2022-12-22 13:10  0%   ` Marius Amado-Alves
  1 sibling, 0 replies; 200+ results
From: Marius Amado-Alves @ 2022-12-22 13:10 UTC (permalink / raw)


On Friday, 1 November 2019 at 13:51:27 UTC, Shark8 wrote:

> And there's an all-Ada graph-database called MNESON that I'm poking at to try to use Ada.Containers rather than the containers it's using. (Shark8)

Did you manage to do that?

Today I put Mneson on GitHub, including an adaptation of the 2005 code to build on present GNAT, but still with the non standard container lib.

^ permalink raw reply	[relevance 0%]

* Re: Compiler error (2) ?
  2022-09-26  8:47 10%   ` reinert
@ 2022-09-26  9:59  0%     ` reinert
  0 siblings, 0 replies; 200+ results
From: reinert @ 2022-09-26  9:59 UTC (permalink / raw)


Sorry for some typos in my latest post, but the intelligent reader should understand :-)

reinert

mandag 26. september 2022 kl. 10:47:16 UTC+2 skrev reinert:
> This is what I (also) get: 
> 
> test1a.adb:16:42: error: expected type "Standard.Integer" 
> test1a.adb:16:42: error: found type "Ada.Containers.Count_Type" 
> 
> compilation of test1a.adb failed 
> 
> gprbuild: *** compilation phase failed 
> error: Command ["gprbuild", "-s", "-j0", "-p", "-P", "/home/reinert/test1a/test1a.gpr"] exited with code 4 
> error: Compilation failed. 
> --------------------------------------------------------------------------------------------------- 
> **However, the following version goes through the compiler and runs 
> (using "subtype n_t is Positive range 3..Positive'Last;" for)
> in the package specification) - confirming what Simon says: 
> 
> with Ada.Text_IO; 
> with Ada.Containers.Vectors; 
> procedure test1a is 
> type s_name_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); 
> for s_name_type use 
> (S0 => 0, S1 => 1, S2 => 2, S3 => 3, S4 => 4, 
> S5 => 5, S6 => 6, S7 => 7, S8 => 8, S9 => 9);
> subtype n_t is Positive range 3..Positive'Last;
> package s_names_p is new Ada.Containers.Vectors
> (Index_Type => n_t, Element_Type => s_name_type); 
> k : integer := 7;
> n : constant integer := 7;
> -- n : constant integer := k; -- uncomment this line and comment out the line above.
> s_names: constant s_names_p.Vector := [for i in 3..n => S0]; 
> begin 
> Ada.Text_IO.Put_Line(s_names'Image); 
> end test1a;
> reinert
> mandag 26. september 2022 kl. 10:34:18 UTC+2 skrev J-P. Rosen: 
> > Please give the exact error message, and why you think it could be a 
> > compiler error. Otherwise, it's hard to help... 
> > Le 26/09/2022 à 08:54, reinert a écrit : 
> > > Hello, 
> > > 
> > > This must reveal a compiler error : 
> > > ------------------------------------------------------------------------------------------------------- 
> > > with Ada.Text_IO; 
> > > with Ada.Containers.Vectors; 
> > > procedure test1a is 
> > > type s_name_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); 
> > > for s_name_type use 
> > > (S0 => 0, S1 => 1, S2 => 2, S3 => 3, S4 => 4, 
> > > S5 => 5, S6 => 6, S7 => 7, S8 => 8, S9 => 9); 
> > > package s_names_p is new Ada.Containers.Vectors 
> > > (Index_Type => Positive, Element_Type => s_name_type); 
> > > k : integer := 7; 
> > > 
> > > -- n : constant integer := 7; -- uncomment this line and comment out the line below. 
> > > n : constant integer := k; 
> > > 
> > > s_names: constant s_names_p.Vector := [for i in 3..n => S0]; 
> > > begin 
> > > Ada.Text_IO.Put_Line(s_names'Image); 
> > > end test1a; 
> > > ------------------------------------------------------------------------------------------------------- 
> > > (compiled using alire and 
> > > package Compiler is 
> > > for Switches ("ada") use ("-gnatwa", "-gnata", "-gnatX", "-gnatwv"); 
> > > end Compiler; 
> > > ------------------------------------------------------------------------------------------------------- 
> > > 
> > > Right? 
> > > 
> > > reinert 
> > -- 
> > J-P. Rosen 
> > Adalog 
> > 2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX 
> > Tel: +33 1 45 29 21 52 
> > https://www.adalog.fr

^ permalink raw reply	[relevance 0%]

* Re: Compiler error (2) ?
  2022-09-26  8:34  0% ` J-P. Rosen
@ 2022-09-26  8:47 10%   ` reinert
  2022-09-26  9:59  0%     ` reinert
  0 siblings, 1 reply; 200+ results
From: reinert @ 2022-09-26  8:47 UTC (permalink / raw)


This is what I (also) get:

test1a.adb:16:42: error: expected type "Standard.Integer"
test1a.adb:16:42: error: found type "Ada.Containers.Count_Type"

   compilation of test1a.adb failed

gprbuild: *** compilation phase failed
error: Command ["gprbuild", "-s", "-j0", "-p", "-P", "/home/reinert/test1a/test1a.gpr"] exited with code 4
error: Compilation failed.
---------------------------------------------------------------------------------------------------
**However, the following version goes through the compiler and runs 
(using "subtype n_t is Positive range 3..Positive'Last;" for)
in the package specification) - confirming what Simon says:

with Ada.Text_IO;
with Ada.Containers.Vectors;
procedure test1a is
   type s_name_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
   for s_name_type use
      (S0 => 0, S1 => 1, S2 => 2, S3 => 3, S4 => 4,
       S5 => 5, S6 => 6, S7 => 7, S8 => 8, S9 => 9);
   subtype n_t is Positive range 3..Positive'Last;
   package s_names_p is new Ada.Containers.Vectors
     (Index_Type => n_t, Element_Type => s_name_type);
   k : integer := 7;

   n : constant integer := 7; 
 --  n : constant integer := k; -- uncomment this line and comment out the line above.

   s_names: constant s_names_p.Vector := [for i in 3..n => S0];
begin
   Ada.Text_IO.Put_Line(s_names'Image);
end test1a;


reinert




mandag 26. september 2022 kl. 10:34:18 UTC+2 skrev J-P. Rosen:
> Please give the exact error message, and why you think it could be a 
> compiler error. Otherwise, it's hard to help...
> Le 26/09/2022 à 08:54, reinert a écrit : 
> > Hello, 
> > 
> > This must reveal a compiler error : 
> > ------------------------------------------------------------------------------------------------------- 
> > with Ada.Text_IO; 
> > with Ada.Containers.Vectors; 
> > procedure test1a is 
> > type s_name_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); 
> > for s_name_type use 
> > (S0 => 0, S1 => 1, S2 => 2, S3 => 3, S4 => 4, 
> > S5 => 5, S6 => 6, S7 => 7, S8 => 8, S9 => 9); 
> > package s_names_p is new Ada.Containers.Vectors 
> > (Index_Type => Positive, Element_Type => s_name_type); 
> > k : integer := 7; 
> > 
> > -- n : constant integer := 7; -- uncomment this line and comment out the line below. 
> > n : constant integer := k; 
> > 
> > s_names: constant s_names_p.Vector := [for i in 3..n => S0]; 
> > begin 
> > Ada.Text_IO.Put_Line(s_names'Image); 
> > end test1a; 
> > ------------------------------------------------------------------------------------------------------- 
> > (compiled using alire and 
> > package Compiler is 
> > for Switches ("ada") use ("-gnatwa", "-gnata", "-gnatX", "-gnatwv"); 
> > end Compiler; 
> > ------------------------------------------------------------------------------------------------------- 
> > 
> > Right? 
> > 
> > reinert
> -- 
> J-P. Rosen 
> Adalog 
> 2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX 
> Tel: +33 1 45 29 21 52 
> https://www.adalog.fr

^ permalink raw reply	[relevance 10%]

* Re: Compiler error (2) ?
  2022-09-26  6:54  9% Compiler error (2) ? reinert
  2022-09-26  8:12  5% ` Simon Wright
@ 2022-09-26  8:34  0% ` J-P. Rosen
  2022-09-26  8:47 10%   ` reinert
  1 sibling, 1 reply; 200+ results
From: J-P. Rosen @ 2022-09-26  8:34 UTC (permalink / raw)


Please give the exact error message, and why you think it could be a 
compiler error. Otherwise, it's hard to help...

Le 26/09/2022 à 08:54, reinert a écrit :
> Hello,
> 
> This must reveal a compiler error :
> -------------------------------------------------------------------------------------------------------
> with Ada.Text_IO;
> with Ada.Containers.Vectors;
> procedure test1a is
>     type s_name_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
>     for s_name_type use
>        (S0 => 0, S1 => 1, S2 => 2, S3 => 3, S4 => 4,
>         S5 => 5, S6 => 6, S7 => 7, S8 => 8, S9 => 9);
>     package s_names_p is new Ada.Containers.Vectors
>       (Index_Type => Positive, Element_Type => s_name_type);
>     k : integer := 7;
> 
> -- n : constant integer := 7; -- uncomment this line and comment out the line below.
>     n : constant integer := k;
> 
>     s_names: constant s_names_p.Vector := [for i in 3..n => S0];
> begin
>     Ada.Text_IO.Put_Line(s_names'Image);
> end test1a;
> -------------------------------------------------------------------------------------------------------
> (compiled using alire and
> package Compiler is
>        for Switches ("ada") use ("-gnatwa", "-gnata", "-gnatX", "-gnatwv");
>     end Compiler;
> -------------------------------------------------------------------------------------------------------
> 
> Right?
> 
> reinert

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


^ permalink raw reply	[relevance 0%]

* Re: Compiler error (2) ?
  2022-09-26  6:54  9% Compiler error (2) ? reinert
@ 2022-09-26  8:12  5% ` Simon Wright
  2022-09-26  8:34  0% ` J-P. Rosen
  1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2022-09-26  8:12 UTC (permalink / raw)


I'm not sure what compiler error you mean.

Agreed that the code as stands reports a strange issue,

    11.    S_Names: constant S_Names_P.Vector := [for I in 3..N => S0];
                                                 |
        >>> error: expected type "Standard.Integer"
        >>> error: found type "Ada.Containers.Count_Type"

which does look like a compiler error (even if it's only misreporting a
valid issue, I'm not sure).

What's more interesting is what happens if you make your suggested
change and it compiles. When you run it,

   $ ./reinert_2 

   raised CONSTRAINT_ERROR : test1a.s_names_p.Replace_Element: Index is
   out of range

Running this under the debugger, with 'catch exception',

   Catchpoint 1, CONSTRAINT_ERROR (test1a.s_names_p.Replace_Element: Index is out of range) at 0x0000000100008ae5 in test1a () at reinert_2.adb:15
   15	   s_names: constant s_names_p.Vector := [for i in 3..n => S0];

So, what's Index?

   (gdb) p index
   No definition of "index" in current context.

Looing at the backtrace,

   (gdb) bt
   [...]
   #4  0x0000000100011711 in test1a.s_names_p.replace_element (container=..., 
       index=6, new_item=s0)
       at /opt/gcc-12.1.0/lib/gcc/x86_64-apple-darwin15/12.1.0/adainclude/a-convec.adb:2522
   #5  0x0000000100008ae5 in test1a () at reinert_2.adb:15

Frame 4 is in the runtime; maybe we can see what's going on,

   (gdb) fr 4
   #4  0x0000000100011711 in test1a.s_names_p.replace_element (container=..., 
       index=6, new_item=s0)
       at /opt/gcc-12.1.0/lib/gcc/x86_64-apple-darwin15/12.1.0/adainclude/a-convec.adb:2522
   2522	         raise Constraint_Error with "Index is out of range";
   (gdb) p index
   $1 = 6

Hmm. What does the source say?

   (gdb) l
   2517	   is
   2518	   begin
   2519	      TE_Check (Container.TC);
   2520	
   2521	      if Checks and then Index > Container.Last then
   2522	         raise Constraint_Error with "Index is out of range";
   2523	      end if;
   2524	
   2525	      Container.Elements.EA (Index) := New_Item;
   2526	   end Replace_Element;

So Index (6) is more than Container.Last:

   (gdb) p container
   $2 = (elements => 0x600000008000, last => 5, tc => (busy => 0, lock => 0))
   (gdb)

6 is certainly more than 5. Where does 5 come from?

Index is Positive. We were hoping to have our container with indices
supporting values up to 7, but the first index of a container has to be
Index_Type'First i.e. 1; the compiler has looked at the length of the
aggregate (5) and created an empty Vector s_names of that length.

Clearly you can't do slices in this context!

^ permalink raw reply	[relevance 5%]

* Compiler error (2) ?
@ 2022-09-26  6:54  9% reinert
  2022-09-26  8:12  5% ` Simon Wright
  2022-09-26  8:34  0% ` J-P. Rosen
  0 siblings, 2 replies; 200+ results
From: reinert @ 2022-09-26  6:54 UTC (permalink / raw)


Hello,

This must reveal a compiler error :
-------------------------------------------------------------------------------------------------------
with Ada.Text_IO;
with Ada.Containers.Vectors;
procedure test1a is
   type s_name_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
   for s_name_type use
      (S0 => 0, S1 => 1, S2 => 2, S3 => 3, S4 => 4,
       S5 => 5, S6 => 6, S7 => 7, S8 => 8, S9 => 9);
   package s_names_p is new Ada.Containers.Vectors
     (Index_Type => Positive, Element_Type => s_name_type);
   k : integer := 7;

-- n : constant integer := 7; -- uncomment this line and comment out the line below.
   n : constant integer := k; 

   s_names: constant s_names_p.Vector := [for i in 3..n => S0];
begin
   Ada.Text_IO.Put_Line(s_names'Image);
end test1a;
-------------------------------------------------------------------------------------------------------
(compiled using alire and  
package Compiler is
      for Switches ("ada") use ("-gnatwa", "-gnata", "-gnatX", "-gnatwv");
   end Compiler;
-------------------------------------------------------------------------------------------------------

Right?

reinert

^ permalink raw reply	[relevance 9%]

* Re: Move semantics
  @ 2022-09-20 14:46 10%                   ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2022-09-20 14:46 UTC (permalink / raw)


On 2022-09-20 14:44, AdaMagica wrote:
> Paul Rubin schrieb am Montag, 19. September 2022 um 20:50:50 UTC+2:
>> I think it refers to the C++ notion.
>> https://en.cppreference.com/w/cpp/utility/move
> 
> What I do not understand: Why should the move operation be less expensive than a copy?
> As I see it: First you have to do a copy, then delete the source.


The standard Ada containers have Move operations.

Containers are of course often implemented with indirection, where the 
container object contains accesses to the data held in the container, so 
a Move operation only has to copy the access values from the source to 
the target, and does not need to copy the data. The access values in the 
source are then nulled, making the source container empty. This is often 
less expensive than copying the data.

Eg. for Vectors, the Ada RM says "Move should not copy elements, and 
should minimize copying of internal data structures."

For the bounded Ada containers, which are not meant to use indirection, 
while there are Move operations the RM says that the implementation 
advice "to minimize copying" does not apply.


^ permalink raw reply	[relevance 10%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-16 15:00  9%             ` Marius Amado-Alves
  2022-09-16 15:42 17%               ` Egil H H
@ 2022-09-16 18:53 18%               ` Björn Lundin
  1 sibling, 0 replies; 200+ results
From: Björn Lundin @ 2022-09-16 18:53 UTC (permalink / raw)


On 2022-09-16 17:00, Marius Amado-Alves wrote:
>>>> "for X of M loop ... end loop".
>>>
>>> Not possible for maps.
>> but you can as
>>> https://programming-idioms.org/idiom/13/iterate-over-map-keys-and-value/1511/ada>
>>
>> with Ada.Containers.Indefinite_Hashed_Maps;
>> with Ada.Strings.Hash;
>> use Ada.Containers;
>> for C in My_Map.Iterate loop
>> Put_Line ("Key = " & Key (C) & ", Value = " & Element (C));
>> end loop;
> 
> Thanks, but this is "in", not "of", requires cursors, and DOES NOT COMPILE, as probably needs like ten lines of boiler plate not show.

well, yes . I thought the for looping stuff was the important part, 
since you done want to call Next.

in or of - does it really matter here?

   for C in My_Map.Iterate loop
or
   for C of My_Map loop
is not that hurtful to my eyes.

   for K,V in My_Map.Iterate loop
or
   for K,V of My_Map loop

getting Key and Value as a tuple would be nicer of course


Anyway, I forgot to instantiate the map. Here's a compileable variant



It outputs
Key = AA, Value =  1
Key = AB, Value =  5

----------------

with Ada.Containers.Hashed_Maps;
with Ada.Strings.Hash;
use Ada.Containers;
with Text_Io ; use Text_IO;

procedure Ite is

   subtype Test_Type is String(1..2);

   package Test_Map_Pkg is new Ada.Containers.Hashed_Maps
     (Test_Type,
      Integer,
      Ada.Strings.Hash,
      "=",
      "=");

   My_Map : Test_Map_Pkg.Map;
   use Test_Map_Pkg;
begin
   My_Map.Insert("AA",1);
   My_Map.Insert("AB",5);

   for C in My_Map.Iterate loop
     Put_Line ("Key = " & Key (C) & ", Value = " & Element (C)'Img);
   end loop;

end Ite;



-- 
/Björn

^ permalink raw reply	[relevance 18%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-16 16:30  9%               ` Marius Amado-Alves
@ 2022-09-16 17:08 18%                 ` Jere
  0 siblings, 0 replies; 200+ results
From: Jere @ 2022-09-16 17:08 UTC (permalink / raw)


On Friday, September 16, 2022 at 12:30:51 PM UTC-4, amado...@gmail.com wrote:
> Jere, ehh.p..., thanks a lot, your complete code was very helpful. 
> For some reason I tried to write for maps as for vectors and it did not pass. 
> I see now some forms do pass. 
> Sorry for the entropy. 
> As you note, still not possible to access the Key with the "of" form. 
> 
> /* 
> And the form
> for (C : My_Maps.Cursor) of My_Map.Iterate loop
> does not pass. Must be "in" 
> */ 
> 
> Thanks all.
 No problem at all.  Yeah, all the standard Ada containers use the "of" form to iterate
over elements and the "in" form to iterate over cursors.  Keys are more like cursors 
from the perspective of the container, so you would need to use some form of "in" 
to get the keys.  

for what it is worth, the example I gave is usable for vectors.  you have to change
names and use append() instead of insert(), but the rest is pretty similar:

*******************************************
    with Ada.Text_IO; use Ada.Text_IO;
    with Ada.Containers.Vectors;
     
    procedure Program is
        package Vectors is new Ada.Containers.Vectors(Positive,Integer);
     
        Vector : Vectors.Vector;
     
    begin
     
        Vector.Append(10);
        Vector.Append(20);
        Vector.Append(30);
        Vector.Append(40);
     
        for Element of Vector loop
            Put_Line(Element'Image);
        end loop;   
    end Program;
**********************************************
Output:
10
 20
 30
 40
*******************************************
IDEONE compiler link:  https://ideone.com/3Ic49d#stdout

So it may depend on how your vector code was originally setup.  
The above is how I typically loop through a vector, which works
for maps and other Ada containers as well.  

Hope that helps!

^ permalink raw reply	[relevance 18%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-16 16:03  8%             ` Marius Amado-Alves
@ 2022-09-16 16:30  9%               ` Marius Amado-Alves
  2022-09-16 17:08 18%                 ` Jere
  0 siblings, 1 reply; 200+ results
From: Marius Amado-Alves @ 2022-09-16 16:30 UTC (permalink / raw)


Jere, ehh.p..., thanks a lot, your complete code was very helpful.
For some reason I tried to write for maps as for vectors and it did not pass.
I see now some forms do pass.
Sorry for the entropy.
As you note, still not possible to access the Key with the "of" form.

/*
And the form
for (C : My_Maps.Cursor) of My_Map.Iterate loop
does not pass. Must be "in"
*/

Thanks all.

^ permalink raw reply	[relevance 9%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-15 17:22  9%           ` Dmitry A. Kazakov
@ 2022-09-16 16:03  8%             ` Marius Amado-Alves
  2022-09-16 16:30  9%               ` Marius Amado-Alves
  0 siblings, 1 reply; 200+ results
From: Marius Amado-Alves @ 2022-09-16 16:03 UTC (permalink / raw)


> That is cursors/iterators for you. They are nothing but dressed up 
> pointers. Should never be there, IMO.  (Dmitry)

Indeed. I've participated in the initial Containers Ada Issue. Managed to get indefinite types in, but lost the fight against the C++STL copy-over (cf. my paper in Ada-Europe 2004).

> In my containers I use positive index 1..<size> instead.

As it should be. I've been pondering using your containers for a long time. Only reason I'm still using Ada's is that they come ready to use with the language. I hate configuration management. But now with Alire I expect configuration work be unavoidable, so probably I'll start using your library at last:-) Read your B_Tree stuff recently. Cool stuff. The separation of storage (RAM, disk...) and structure (vector, map...) still not clear cut. Theoretically storage pools could do this, but Ada does not help her self. I tried a design once with generics (instead of storage pools): also too verbose

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

^ permalink raw reply	[relevance 8%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-15 17:11  9%         ` Marius Amado-Alves
  2022-09-15 17:22  9%           ` Dmitry A. Kazakov
  2022-09-16 11:33 19%           ` Björn Lundin
@ 2022-09-16 15:47 17%           ` Jere
  2 siblings, 0 replies; 200+ results
From: Jere @ 2022-09-16 15:47 UTC (permalink / raw)


On Thursday, September 15, 2022 at 1:11:19 PM UTC-4, amado...@gmail.com wrote:
> Thanks, Niklas. 
> 
> > ... There are functions First and Next ... procedure Iterate ... 
> 
> Too verbose and error-prone (forget the Next and you get an endless loop).
> > "for X of M loop ... end loop".
> Not possible for maps.

I'm not sure I understand.  I tried it in gnat 11 and it compiled just fine:
*************************************************
    with Ada.Text_IO; use Ada.Text_IO;
    with Ada.Containers.Ordered_Maps;
     
    procedure Program is
        package Maps is new Ada.Containers.Ordered_Maps(Integer,Integer);
     
        Map : Maps.Map;
     
    begin
     
        Map.Insert(1,10);
        Map.Insert(2,20);
        Map.Insert(3,30);
        Map.Insert(4,40);
     
        for Element of Map loop
            Put_Line(Element'Image);
        end loop;   
    end Program;
*************************************************
Output:
10
 20
 30
 40
*************************************************

Even tried it on some online compilers and it compiled and ran:
IDEONE online compiler:  https://ideone.com/H2oEZt

If this isn't what you mean, what is the missing feature.?  the "for of" version does work for maps as far as I can tell.

^ permalink raw reply	[relevance 17%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-16 15:00  9%             ` Marius Amado-Alves
@ 2022-09-16 15:42 17%               ` Egil H H
  2022-09-16 18:53 18%               ` Björn Lundin
  1 sibling, 0 replies; 200+ results
From: Egil H H @ 2022-09-16 15:42 UTC (permalink / raw)


On Friday, September 16, 2022 at 5:00:29 PM UTC+2, amado...@gmail.com wrote:
> > >> "for X of M loop ... end loop". 
> > > 
> > > Not possible for maps. 
> > but you can as 
> > >https://programming-idioms.org/idiom/13/iterate-over-map-keys-and-value/1511/ada> 
> >
> > with Ada.Containers.Indefinite_Hashed_Maps; 
> > with Ada.Strings.Hash; 
> > use Ada.Containers; 
> > for C in My_Map.Iterate loop 
> > Put_Line ("Key = " & Key (C) & ", Value = " & Element (C)); 
> > end loop;
> Thanks, but this is "in", not "of", requires cursors, and DOES NOT COMPILE, as probably needs like ten lines of boiler plate not show.

(sorry for any botched formatting...)

with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;
with Ada.Text_IO;

procedure Iteration is
   package My_Maps is 
      new Ada.Containers.Indefinite_Hashed_Maps
         (String, Integer, Ada.Strings.Hash, "=");
   
   My_Map : My_Maps.Map;
begin
   My_Map.Include("One", 1);
   My_Map.Include("Two", 2);
   My_Map.Include("Three", 3);

   for C in My_Map.Iterate loop
      Ada.Text_IO.Put_Line(My_Maps.Key(C) & My_Maps.Element(C)'Image);
   end loop;
   
   for Element of My_Map loop
      Ada.Text_IO.Put_Line(Element'Image);
   end loop;
   
   -- Ada_2022:
   -- for (C : My_Maps.Cursor) of My_Map.Iterate loop
   --    Ada.Text_IO.Put_Line(My_Maps.Key(C) & My_Maps.Element(C)'Image);
   -- end loop Ada_2022;
   
end Iteration;

I don't know why they left out a two-parameter version of the Iterate procedure for Ada 2022 Maps,
   -- for (Key, Element) of My_Map.Iterate loop
would've been nice, just like
   -- for (Name, Val) of Ada.Environment_Variables.Iterate(<>) loop



^ permalink raw reply	[relevance 17%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-16 11:33 19%           ` Björn Lundin
@ 2022-09-16 15:00  9%             ` Marius Amado-Alves
  2022-09-16 15:42 17%               ` Egil H H
  2022-09-16 18:53 18%               ` Björn Lundin
  0 siblings, 2 replies; 200+ results
From: Marius Amado-Alves @ 2022-09-16 15:00 UTC (permalink / raw)


> >> "for X of M loop ... end loop". 
> > 
> > Not possible for maps.
> but you can as 
> >https://programming-idioms.org/idiom/13/iterate-over-map-keys-and-value/1511/ada> 
> 
> with Ada.Containers.Indefinite_Hashed_Maps; 
> with Ada.Strings.Hash; 
> use Ada.Containers; 
> for C in My_Map.Iterate loop 
> Put_Line ("Key = " & Key (C) & ", Value = " & Element (C)); 
> end loop; 

Thanks, but this is "in", not "of", requires cursors, and DOES NOT COMPILE, as probably needs like ten lines of boiler plate not show.

^ permalink raw reply	[relevance 9%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-15 17:11  9%         ` Marius Amado-Alves
  2022-09-15 17:22  9%           ` Dmitry A. Kazakov
@ 2022-09-16 11:33 19%           ` Björn Lundin
  2022-09-16 15:00  9%             ` Marius Amado-Alves
  2022-09-16 15:47 17%           ` Jere
  2 siblings, 1 reply; 200+ results
From: Björn Lundin @ 2022-09-16 11:33 UTC (permalink / raw)


On 2022-09-15 19:11, Marius Amado-Alves wrote:
> Thanks, Niklas.
> 
>> ... There are functions First and Next ... procedure Iterate ...
> 
> Too verbose and error-prone (forget the Next and you get an endless loop).
> 
>> "for X of M loop ... end loop".
> 
> Not possible for maps.


but you can as
 >https://programming-idioms.org/idiom/13/iterate-over-map-keys-and-value/1511/ada>

shows (as below)

--Access each key k with its value x from an associative array mymap,
-- and print them.

with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;

use Ada.Containers;

for C in My_Map.Iterate loop
    Put_Line ("Key = " & Key (C) & ", Value = " & Element (C));
end loop;



-- 
/Björn

^ permalink raw reply	[relevance 19%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-15 17:11  9%         ` Marius Amado-Alves
@ 2022-09-15 17:22  9%           ` Dmitry A. Kazakov
  2022-09-16 16:03  8%             ` Marius Amado-Alves
  2022-09-16 11:33 19%           ` Björn Lundin
  2022-09-16 15:47 17%           ` Jere
  2 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2022-09-15 17:22 UTC (permalink / raw)


On 2022-09-15 19:11, Marius Amado-Alves wrote:
> Thanks, Niklas.
> 
>> ... There are functions First and Next ... procedure Iterate ...
> 
> Too verbose and error-prone (forget the Next and you get an endless loop).

That is cursors/iterators for you. They are nothing but dressed up 
pointers. Should never be there, IMO.

In my containers I use positive index 1..<size> instead.

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

^ permalink raw reply	[relevance 9%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-15 15:03  8%       ` Niklas Holsti
@ 2022-09-15 17:11  9%         ` Marius Amado-Alves
  2022-09-15 17:22  9%           ` Dmitry A. Kazakov
                             ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Marius Amado-Alves @ 2022-09-15 17:11 UTC (permalink / raw)


Thanks, Niklas.

> ... There are functions First and Next ... procedure Iterate ...

Too verbose and error-prone (forget the Next and you get an endless loop).

> "for X of M loop ... end loop".

Not possible for maps.

^ permalink raw reply	[relevance 9%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-15 14:26  9%     ` Marius Amado-Alves
@ 2022-09-15 15:03  8%       ` Niklas Holsti
  2022-09-15 17:11  9%         ` Marius Amado-Alves
  0 siblings, 1 reply; 200+ results
From: Niklas Holsti @ 2022-09-15 15:03 UTC (permalink / raw)


On 2022-09-15 17:26, Marius Amado-Alves wrote:
>> ... it seems best to have compilers for pre-202x at hand in case a
>> program needs Ada 2005 containers or Ada 2012 containers. (G.B.)
> 
> Sorry, but is all this new stuff not backward-compatible? (Except
> maybe a teeny thing or two, easy to fix.)


The incompatibility seems to arise only if one derives from the 
container types defined in the library. I don't think that is often 
needed in an application.


> BTW, do the new containers fix map iteration? I'm always stupefied at
> not being possible to iterate a map like you do a vector.


Maps supported iteration already in Ada 2005, when the standard 
containers were added to Ada. There are functions First and Next, to 
give the first map element and to advance from an element to the next 
element, and also a procedure Iterate that traverses the whole map and 
performs some action on each element. In current Ada, one can also 
iterate over a map with the "generalized loop iteration" syntax, as in 
"for X of M loop ... end loop".

^ permalink raw reply	[relevance 8%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-15  7:13  9%   ` G.B.
@ 2022-09-15 14:26  9%     ` Marius Amado-Alves
  2022-09-15 15:03  8%       ` Niklas Holsti
  0 siblings, 1 reply; 200+ results
From: Marius Amado-Alves @ 2022-09-15 14:26 UTC (permalink / raw)


> ... it seems best to have compilers for pre-202x at hand 
> in case a program needs Ada 2005 containers or Ada 2012 containers. (G.B.)

Sorry, but is all this new stuff not backward-compatible? (Except maybe a teeny thing or two, easy to fix.)

BTW, do the new containers fix map iteration? I'm always stupefied at not being possible to iterate a map like you do a vector.

Thanks.

^ permalink raw reply	[relevance 9%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-14 16:04  9% ` Egil H H
@ 2022-09-15  7:13  9%   ` G.B.
  2022-09-15 14:26  9%     ` Marius Amado-Alves
  0 siblings, 1 reply; 200+ results
From: G.B. @ 2022-09-15  7:13 UTC (permalink / raw)


On 14.09.22 18:04, Egil H H wrote:
> On Wednesday, September 14, 2022 at 2:36:11 PM UTC+2, G.B. wrote:
>>
>> I couldn't find these functions in the LRM's package specifications.
> <snip>
>> Am I missing something?
> 
> They're part of Ada 2022, needed for the new container aggregate syntax.
> 
> See,
> http://www.ada-auth.org/standards/2xrm/html/RM-A-18-5.html
> http://www.ada-auth.org/standards/2xrm/html/RM-4-3-5.html

Thanks. As the interface of Ada's containers is chang^H^H^H^H^Hbeing
improved, it seems best to have compilers for pre-202x at hand
in case a program needs Ada 2005 containers or Ada 2012 containers.

^ permalink raw reply	[relevance 9%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-14 12:36 18% Non-standard functions in GNAT's Ada.Containers packages? G.B.
@ 2022-09-14 16:04  9% ` Egil H H
  2022-09-15  7:13  9%   ` G.B.
  0 siblings, 1 reply; 200+ results
From: Egil H H @ 2022-09-14 16:04 UTC (permalink / raw)


On Wednesday, September 14, 2022 at 2:36:11 PM UTC+2, G.B. wrote:
> In Ada.Containers.{Kind}s of GCC 11.2, I find functions defined 
> by the pattern: 
> 
> function Empty (Capacity : Count_Type := 1000) return {Kind}; 
> 
> I couldn't find these functions in the LRM's package specifications. 
<snip> 
> Am I missing something?

They're part of Ada 2022, needed for the new container aggregate syntax.

See,
http://www.ada-auth.org/standards/2xrm/html/RM-A-18-5.html
http://www.ada-auth.org/standards/2xrm/html/RM-4-3-5.html

^ permalink raw reply	[relevance 9%]

* Non-standard functions in GNAT's Ada.Containers packages?
@ 2022-09-14 12:36 18% G.B.
  2022-09-14 16:04  9% ` Egil H H
  0 siblings, 1 reply; 200+ results
From: G.B. @ 2022-09-14 12:36 UTC (permalink / raw)


In Ada.Containers.{Kind}s of GCC 11.2, I find functions defined
by the pattern:

   function Empty (Capacity : Count_Type := 1000) return {Kind};

I couldn't find these functions in the LRM's package specifications.

Upon type derivation, then, these functions appear to require
non-portable source text when using GNAT's standard Ada
containers.  For example,

     package Real_Vectors is new Ada.Containers.Vectors (...);
     type Fancy_Vectors is new Real_Vectors.Vector with private;

     18.     type Fancy_Vectors is new Real_Vectors.Vector with record
                  |
         >>> type must be declared abstract or "Empty" overridden
         >>> "Empty" has been inherited at line 14
         >>> "Empty" has been inherited from subprogram at a-convec.ads:125, instance at line 8


While composition would not incur this effect, etc. etc., still
the resulting source text would need to override a "standard" function,
but this function, Empty, might not exist at all when using other
standard Ada compilers.

Am I missing something?

^ permalink raw reply	[relevance 18%]

* Re: Calling inherited primitive operations in Ada
  2022-09-05  6:56 10%                               ` Emmanuel Briot
  2022-09-05  7:34  0%                                 ` Dmitry A. Kazakov
@ 2022-09-05  9:30  6%                                 ` Jeffrey R.Carter
  1 sibling, 0 replies; 200+ results
From: Jeffrey R.Carter @ 2022-09-05  9:30 UTC (permalink / raw)


On 2022-09-05 08:56, Emmanuel Briot wrote:
> 
> I definitely see the same issue. The way my library is trying to workaround that is as follows:
> Those instantiations are only needed for people who want/need to control every aspects of their containers, for instance
> how elements are stored, how/when memory is allocated, what is the growth strategy for vectors, and so on.
> Most users should not have to care about that in practice. So we use code generation at compile time to generate
> high-level packages similar to the Ada containers, with a limited set of formal parameters (in src/generated, to be
> more specific). We can generate bounded/unbounded versions, definite/indefinite versions, and any combination of
> those.

This seems backwards. The user should encounter the forms most likely to be used 
first; if part of the packages are in a subdirectory, those should be the ones 
less likely for the typical user to use.

> Although it is certainly true that using holders works, it is not applicable when designing a containers library that intends to be
> mostly compatible with Ada containers. The latter have chosen, long ago and before Holder was a thing, to have definite and
> indefinite versions. The main benefit to this approach is that users still retrieve directly the type they are interested in (e.g. String)
> rather than a holder-to-string.

Before Ada.Containers existed, I commonly used definite data structures from the 
PragmARCs with Unbounded_String, which is partly a specialized holder for String 
(and partly a specialized Vector for Positive/Character). Generalizing from this 
led to implementing a Holder pkg.

When I said a holder is the only indefinite pkg that is needed, I meant to imply 
that other indefinite structures would be implemented using the definite form + 
holder.

-- 
Jeff Carter
“Bug rates in C++ are running higher even than C ...”
Stephen F. Zeigler
216

^ permalink raw reply	[relevance 6%]

* Re: Calling inherited primitive operations in Ada
  2022-09-05  6:56 10%                               ` Emmanuel Briot
@ 2022-09-05  7:34  0%                                 ` Dmitry A. Kazakov
  2022-09-05  9:30  6%                                 ` Jeffrey R.Carter
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2022-09-05  7:34 UTC (permalink / raw)


On 2022-09-05 08:56, Emmanuel Briot wrote:

> Although it is certainly true that using holders works, it is not applicable when designing a containers library that intends to be
> mostly compatible with Ada containers.

Right. Holder requires finalization and finalization means language 
prescribed finalization lists which is highly undesirable in many cases.

> The main benefit to this approach is that users still retrieve directly the type they are interested in (e.g. String)
> rather than a holder-to-string.

And that the container designer has control over the pool where the 
items get actually allocated.

> I must admit I have very limited experience with Holders, which I have never used in production code (nor, apparently, have my
> colleagues and ex-colleagues).

I have been using the idea for a long time, since Ada 95 before the 
standard library had them. In my experience holders multiply the number 
of container variants:

1. Definite elements
2. Indefinite elements
    +
3. Holder elements in the interface (and maybe implementation)

The third gets a holder package as a formal parameter or, alternatively, 
is a child of a holder package (for performance reasons). The container 
interface has direct operations in terms of the Element_Type as well as 
in terms of the holder type.

Sometimes the holder variant is actually the indefinite one that 
promotes holders only in its interface.

P.S. In my opinion helper types/package is an evil of far greater scale 
than any premature optimization!

The programmers doing the latter at least try to understand the code 
they write.

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

^ permalink raw reply	[relevance 0%]

* Re: Calling inherited primitive operations in Ada
  2022-09-03 19:00 10%                             ` Simon Wright
@ 2022-09-05  6:56 10%                               ` Emmanuel Briot
  2022-09-05  7:34  0%                                 ` Dmitry A. Kazakov
  2022-09-05  9:30  6%                                 ` Jeffrey R.Carter
  0 siblings, 2 replies; 200+ results
From: Emmanuel Briot @ 2022-09-05  6:56 UTC (permalink / raw)


Jeff Carter:
> Where is that? All I saw in my quick look were Maps, Maps.Generics, and Maps.Impl.

Simon Wright:
> And this was one reason that I didn't put up any arguments at Ada Europe
> 2002 for the Ada 95 Booch Components to form a basis for Ada.Containers
> - you'd need 3 instantiations, one after the other.

I definitely see the same issue. The way my library is trying to workaround that is as follows:
Those instantiations are only needed for people who want/need to control every aspects of their containers, for instance
how elements are stored, how/when memory is allocated, what is the growth strategy for vectors, and so on.
Most users should not have to care about that in practice. So we use code generation at compile time to generate
high-level packages similar to the Ada containers, with a limited set of formal parameters (in src/generated, to be
more specific). We can generate bounded/unbounded versions, definite/indefinite versions, and any combination of
those.
One of the intentions of the library, initially, had been the implementation of the Ada containers and SPARK containers
in GNAT, as a way to share as much code as possible between the two.


Randy Brukardt:
> Assuming otherwise is certainly premature optimization.

I am quoting a bit out of context, though I believe it is close enough. Designers of containers must care about performance
from the get-go. Otherwise, people might just as well use a list for everything and just traverse the list all the time. We all
know this would be way too inefficient, of course, which is why there are various sorts of containers.
Anyone who has actually written performance-sensitive code knows that memory allocations is definitely something to watch
out for, and the library design should definitely take that into account.

Jeff Carter:
> The only indefinite data structure that is needed seems to be holders

Although it is certainly true that using holders works, it is not applicable when designing a containers library that intends to be
mostly compatible with Ada containers. The latter have chosen, long ago and before Holder was a thing, to have definite and
indefinite versions. The main benefit to this approach is that users still retrieve directly the type they are interested in (e.g. String)
rather than a holder-to-string.
I must admit I have very limited experience with Holders, which I have never used in production code (nor, apparently, have my
colleagues and ex-colleagues). 


Randy Brukardt:
> Ada *DOES* support default values for formal parameters of generics

Hey, I just discovered that, thanks Randy ! For people who also did not know that:

    generic
         type Item_Count is range <>  or use Natural;
    package Gen is

It is supported by GNAT's newer versions (I don't know when it was implemented though)

^ permalink raw reply	[relevance 10%]

* Re: Calling inherited primitive operations in Ada
  2022-09-03  0:07 10%                           ` Randy Brukardt
@ 2022-09-03 19:00 10%                             ` Simon Wright
  2022-09-05  6:56 10%                               ` Emmanuel Briot
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2022-09-03 19:00 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> But they violate the #1 principle of the Ada.Containers: ease of
> use. One principle that we insisted on was that a single instantiation
> was the maximum we would use

And this was one reason that I didn't put up any arguments at Ada Europe
2002 for the Ada 95 Booch Components to form a basis for Ada.Containers
- you'd need 3 instantiations, one after the other.

--  A company's Fleet holds a number of Cars.

   with BC.Containers.Collections.Bounded;
   with Cars;
   package My_Fleet is

      use type Cars.Car;

      package Abstract_Car_Containers
      is new BC.Containers (Cars.Car);

      package Abstract_Car_Collections
      is new Abstract_Car_Containers.Collections;

      package Fleets
      is new Abstract_Car_Collections.Bounded (Maximum_Size => 30);

      The_Fleet : Fleets.Collection;

   end My_Fleet;

The other was a lack of consistency in the implementation (Length?
Size?).

^ permalink raw reply	[relevance 10%]

* Re: Calling inherited primitive operations in Ada
  2022-09-02  6:11  8%                         ` Emmanuel Briot
  2022-09-02 10:55  0%                           ` Jeffrey R.Carter
@ 2022-09-03  0:07 10%                           ` Randy Brukardt
  2022-09-03 19:00 10%                             ` Simon Wright
  1 sibling, 1 reply; 200+ results
From: Randy Brukardt @ 2022-09-03  0:07 UTC (permalink / raw)


"Emmanuel Briot" <briot.emmanuel@gmail.com> wrote in message 
news:b678b499-0cb1-4c64-a88f-cfa9a79893e6n@googlegroups.com...

>These packages are mostly implementation details. They are used to build 
>high-level
>packages similar to the Ada containers, except with much better code reuse, 
>more
> efficient, and SPARK-provable.

(Wading in where I should probably not tread... :-)

But they violate the #1 principle of the Ada.Containers: ease of use. One 
principle that we insisted on was that a single instantiation was the 
maximum we would use, because we did not want people moving from arrays to 
containers to have to replace one declaration with a half page of magic 
incantations. (This is the reason that there is no container interface, for 
one consequence, and certainly no signature packages.)

In general, people either undertand and like signature packages, or really 
do not understand them and just use them when insisted on. The standard 
containers in Ada needed to be usable by the maximum number of users, and 
insisting on bells and whistles that many don't understand does not help.

                        Randy.




^ permalink raw reply	[relevance 10%]

* Re: Calling inherited primitive operations in Ada
  2022-09-02  6:11  8%                         ` Emmanuel Briot
@ 2022-09-02 10:55  0%                           ` Jeffrey R.Carter
  2022-09-03  0:07 10%                           ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Jeffrey R.Carter @ 2022-09-02 10:55 UTC (permalink / raw)


On 2022-09-02 08:11, Emmanuel Briot wrote:
> 
> I did point you to the full repository if you prefer an extensive, real-life code sample. This was just an extract showing the gist of the issue.
> 
> One can check the full code and extensive documentation on the design in the github repository.

Yes, I looked at it, and found it over complicated, difficult to understand, and 
not user friendly. There appears to be extensive HTML documentation, but it can 
only be viewed as HTML source in Github, which is not easy to read, so I didn't.

Apparently a user who wants a map has to supply a significant part of what I 
consider the implementation of the map. As such, this may serve as a hidden 
layer to implement a library of data structures, but seems unusable for the 
typical user, for whom using a hashed-map abstraction should be as simple as

function Hash (Key : in Identifier) return Hash_Value;

package Maps is new Lib.Maps
    (Identifier => Identifier, Associated_Value => Associated_Value);

I was not willing to spend more than about 15 minutes trying to understand this, 
so I may be missing something.

> These packages are mostly implementation details. They are used to build high-level packages similar to the Ada containers

This agrees with what I was saying earlier. But even for such a use, simplicity 
and ease of understanding are still the most important aspects of S/W. If 
attaining them involves some code duplication they are worth that price.

>> that pkg Keys serves some actual role in the spec of Maps, then someone wanting
>> to use pkg Maps will need to understand that role, which involves understanding
>> Definite_Elements, which involves understanding pkg Traits, which involves
>> understanding Elements.
> 
> which involves understanding Ada, which involves understanding the compiler, which involves understanding the kernel sources, ...
> How many times have you checked the whole sources of the GNAT runtime to understand how they implemented the Ada containers ?

One understands a pkg by understanding its spec. I find it hard to believe that 
you could actually think that I meant one had to understand the implementation 
as well.

-- 
Jeff Carter
"Apple juice and Darvon is fantastic together."
Play It Again, Sam
127

^ permalink raw reply	[relevance 0%]

* Re: Calling inherited primitive operations in Ada
  @ 2022-09-02  6:11  8%                         ` Emmanuel Briot
  2022-09-02 10:55  0%                           ` Jeffrey R.Carter
  2022-09-03  0:07 10%                           ` Randy Brukardt
  0 siblings, 2 replies; 200+ results
From: Emmanuel Briot @ 2022-09-02  6:11 UTC (permalink / raw)


> As presented, this seems very over complicated. Elements and Definite_Elements 
> add no value, and this is just a complex way of writing 

I did point you to the full repository if you prefer an extensive, real-life code sample. This was just an extract showing the gist of the issue.

> One hopes that the actual library makes better use of these pkgs than this small 
> example.

One can check the full code and extensive documentation on the design in the github repository.
This is called code reuse, was invented quite a while ago.
These packages are mostly implementation details. They are used to build high-level packages similar to the Ada containers, except with much better code reuse, more efficient, and SPARK-provable.

> Ada has excellent features for hiding, but these are not among them. Assuming 

And that's exactly our point in this discussion. Ada on the whole is very good (we would not be using it otherwise), but it does have a number of limitations which are sometimes a pain, this being one of them. Not acknowledging the limitations when they exist is naive, all languages have them.

> that pkg Keys serves some actual role in the spec of Maps, then someone wanting 
> to use pkg Maps will need to understand that role, which involves understanding 
> Definite_Elements, which involves understanding pkg Traits, which involves 
> understanding Elements. 

which involves understanding Ada, which involves understanding the compiler, which involves understanding the kernel sources, ...
How many times have you checked the whole sources of the GNAT runtime to understand how they implemented the Ada containers ?

Emmanuel

^ permalink raw reply	[relevance 8%]

* Bugged Multiway_Tree package?
@ 2022-06-13 21:49  7% Devin Rozsas
  0 siblings, 0 replies; 200+ results
From: Devin Rozsas @ 2022-06-13 21:49 UTC (permalink / raw)


I've been trying to instantiate `Ada.Containers.Multiway_Trees`, but I was getting some error message like "Value for Disable_Controlled must be static" or something of the sort.
I looked at GNAT's source in `a-comutr.adb`, and indeed, at lines 54 and 79, there are non-static expressions for `Disable_Controlled`.

Both the AdaCore 2021 installer and Fedora's repo versions of GNAT have this in the source-code.

Is this a bug?

^ permalink raw reply	[relevance 7%]

* Question on in/out parameters
@ 2022-04-30  8:57 10% reinert
  0 siblings, 0 replies; 200+ results
From: reinert @ 2022-04-30  8:57 UTC (permalink / raw)


Hello,

I expected an "out" parameter in a procedure to be like declaring the parameter "from scratch" (with actual initial default value). For my compiler (GNAT Community Edition, May 2021) it seems like the out parameters brings in content from the calling procedure. Should it be like this?

Below is a test program to illustrate.

reinert

with Ada.Containers; use Ada.Containers;
with Ada.Containers.Vectors;
with Ada.Text_IO; use Ada.Text_IO;
procedure test2 is

   package Integer_Vectors is new Ada.Containers.Vectors
       (Index_Type   => Natural, Element_Type => Integer);
   use Integer_Vectors;

   V : Vector := 10 & 20;

   procedure rk_in_out(W : in out Vector) is
   begin
     W.Append(30); W.Append(40);
   end rk_in_out;

   procedure rk_out(W :    out Vector) is
   begin
     W.Clear;  -- I expected this statement to be redundant since W is "out parameter" (try to remove it and see if results remain the same.)?
     W.Append(30); W.Append(40);
   end rk_out;

begin

   New_Line;
   Put ("First V  : ");
   for e of V loop
       Put(e'Image & " ");
   end loop;

   rk_in_out(W => V);
   New_Line;
   Put ("Second V : ");
   for e of V loop
       Put(e'Image & " ");
   end loop;

   rk_out(W => V);
   New_Line;
   Put ("Third V :  ");
   for e of V loop
       Put(e'Image & " ");
   end loop;

end test2;


^ permalink raw reply	[relevance 10%]

* Re: Unchecked_Deallocation with tagged types
  @ 2022-04-18  5:51  7%                   ` Thomas
  0 siblings, 0 replies; 200+ results
From: Thomas @ 2022-04-18  5:51 UTC (permalink / raw)


In article <s5naeu$r4c$1@gioia.aioe.org>,
 "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote:

> On 2021-04-20 20:53, Randy Brukardt wrote:
> 
> > OTOH, an Ada
> > follow-on would most likely have access types with automatic deallocation as
> > proposed by Tucker in one of the many AIs on ownership.

who is Tucker, and where can i read him, please? :-)

> > So using any form of
> > explicit deallocation would be discouraged (as would the use of raw pointer
> > types).
> 
> I do not understand how that could work, it sounds like a halting 
> problem to me,

i feel that:

1)
afaik, non-pool-specific access-to-variable types, which should point on 
aliased objects, are not dangerous, as long as neither new nor 
Unchecked_Deallocation are used.

2)
pool-specific access-to-variable types should mostly look like 
Ada.Containers.Indefinite_Holders.
there is missing one for definite limited types,
and i hope it's possible to also make it for indefinite limited types
(if it's not allowed in Ada, it should be planned for an Ada follow-on).


> but anyway, where is a problem? Add a whole new hierarchy 
> of access types independent on the existing one.

anyway, we can begin to think about it, and see later what it should 
become.
but if Tucker already begun to think about it, i would prefer read him 
before develop my own think, to avoid redo what he already did :-)

-- 
RAPID maintainer
http://savannah.nongnu.org/projects/rapid/

^ permalink raw reply	[relevance 7%]

* Re: Unchecked_Deallocation with tagged types
  @ 2022-04-18  1:51 10%                       ` Thomas
  0 siblings, 0 replies; 200+ results
From: Thomas @ 2022-04-18  1:51 UTC (permalink / raw)


In article <s5vpul$ldb$1@franka.jacob-sparre.dk>,
 "Randy Brukardt" <randy@rrsoftware.com> wrote:

> "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
> news:ie8uagFqaf2U1@mid.individual.net...
> > On 2021-04-20 23:32, Jeffrey R. Carter wrote:
> >> On 4/20/21 8:53 PM, Randy Brukardt wrote:
> >>>
> >>> 'Free makes more sense in a new language (an Ada follow-on).
> >>
> >> Right. I don't think it would be a good idea to add it to Ada.
> >>
> >> But I think a new language should not have pointers at all.
> >>
> >> No more radical than not having arrays.
> >
> > It seems to me that a language without arrays and pointers would be very 
> > difficult to use in an embedded, real-time, close-to-HW context. So we 
> > would lose the nice wide-spectrum nature of Ada.

i like "the nice wide-spectrum nature of Ada" :-)
If I got it right, it is the thickness*, that is, it goes both far in 
low level and far in high level.

* Natacha Porte, https://www.youtube.com/watch?v=b5lRyBRk0d8&t=430s 
(during 1:10 - sorry, it's only in french)


> 
> It's important that a new language have a way to interface to existing 
> hardware and software. So there has to be something that maps to C arrays 
> and pointers (and the equivalent for hardware). But that doesn't necessarily 
> have to be something that is used outside of interfacing. An Ada example is 
> Unchecked_Unions -- they exist for interfacing but shouldn't be used 
> otherwise.

i don't know much "exotic things" (for me) like embedded or real-time 
programming,
but i would not take the risk to exclude users who need low level in 
various cases (not only in interfaces),
so i think it would be better to keep a full thickness with the ability 
to go far in low level at any place it is considered usefull.

> A fixed vector type and a raw general access type would do the 
> trick, but those could be something that are almost never used outside of 
> interfacing packages.

an other point here, is the ability to create new structures that could 
be considered as "basic" later.

for example Ada.Containers.Multiway_Trees seems to be based on 
Ada.Containers.Doubly_Linked_Lists,
and i don't know if it could be needed / usefull to have trees based on 
Ada.Containers.Vectors,
but based on Ada.Containers.Ordered_Maps, certainly!

and sometimes using other high level data structures would be enough, 
but probably sometimes it would be non-optimal, and maybe, in the worst 
case, it could be impossible (especially in the event that we had not 
foreseen all the needed high level data structures)


so, i think:

- we could keep arrays as is, no matter if they are rarly used.

- for access types, it would be nice to find a kind of "controlled 
access type" that allows:
  - to access the "raw general access type", as low level type,
    when needed,
  - to need not Unchecked_Deallocation, making automatic Deallocation,
  - and which would not be too much high level
    (for example Ada.Containers.Indefinite_Holders is fine).

-- 
RAPID maintainer
http://savannah.nongnu.org/projects/rapid/

^ permalink raw reply	[relevance 10%]

* Re: use clauses
  2022-04-12 23:25  7%                   ` use clauses Thomas
@ 2022-04-13  1:05  0%                     ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2022-04-13  1:05 UTC (permalink / raw)


"Thomas" <fantome.forums.tDeContes@free.fr.invalid> wrote in message 
news:62560a6b$0$18724$426a74cc@news.free.fr...
> In article <s5vqq9$lou$1@franka.jacob-sparre.dk>,
> "Randy Brukardt" <randy@rrsoftware.com> wrote:
>
>> For me, a naming scheme that discourages the use of (package) use clauses 
>> is
>> a bonus. (Such a scheme makes it easier to avoid use clauses.)
>
> I agree to avoid use clauses.
>
> (I personally prefer Lists.List, like Vincent Marciante -
> i like Ada.Containers.* naming :-) )
>
>
>> I personally
>> only use "use type" in new code (there's tons of old code for which that
>> doesn't work, of course, but that doesn't change the principle).
>
> what do you think about:
> - "use all type" clauses?

This is OK; I don't use them mainly because I only use features implemented 
in Janus/Ada, and "use all type" is not yet implemented there.

The fundamental problem with "use" is that it makes everything visible, and 
then deals with conflicts by making those things invisible again. That's not 
problem for overloadable primitive operations, since the profile is included 
and conflicts only occur when someone has made a lousy design choice 
(creating a routine with the same name and profile as a primitive) [Most 
such conflicts come from maintenance when some existing routine is moved to 
be primitive; in such cases, the original routine simply should be removed.] 
Since "use all type" only works on overloadable primitives (and things that 
work rather like primitives), it's fairly safe. One could make an argument 
that primitive operations should always be visible when the type is (that's 
not the Ada rule, but argubly it would work better in most circumstances) --  
and you should always know to look at primitives anyway when trying to find 
something..

> - List.Clear? (could you remember me how you call that, please?)

For tagged types, you can use prefix notation, so "My_List.Clear" is the 
easiest. With "use all type List", you can write Clear(My_List). If your 
objects have well-choosen names, it's not really needed to have the type 
around for such operations, even when use clauses are in place. Thus, 
"Clear", not "Clear_List", and that works well even when someone uses 
everything in sight (of course, they may have a hard time finding where 
Clear is defined when debugging, but that's their choice).

> - List.Clear does work only if List is tagged?

Right. There are a number of semantic issues for untagged types, the main 
ones having to do with implicit dereference (which occurs in this notation, 
as in any other selected_component notation). If you have a prefix of an 
access type, it gets very messy to determine which dereference is which. And 
just allowing composite types doesn't work well either: a private type that 
is completed with an access type would *lose* operations when it had full 
visibility -- that seems pretty weird.

It originally got limited to tagged types as that was easy to do and didn't 
have semantic issues. We were going to look at generalizing the prefix 
notation again (several people asked about it), but no one made a concrete 
proposal and it never went anywhere for Ada 2022.

                         Randy.


^ permalink raw reply	[relevance 0%]

* use clauses
  @ 2022-04-12 23:25  7%                   ` Thomas
  2022-04-13  1:05  0%                     ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Thomas @ 2022-04-12 23:25 UTC (permalink / raw)


In article <s5vqq9$lou$1@franka.jacob-sparre.dk>,
 "Randy Brukardt" <randy@rrsoftware.com> wrote:

> For me, a naming scheme that discourages the use of (package) use clauses is 
> a bonus. (Such a scheme makes it easier to avoid use clauses.)

I agree to avoid use clauses.

(I personally prefer Lists.List, like Vincent Marciante -
i like Ada.Containers.* naming :-) )


> I personally 
> only use "use type" in new code (there's tons of old code for which that 
> doesn't work, of course, but that doesn't change the principle).

what do you think about:
- "use all type" clauses?
- List.Clear? (could you remember me how you call that, please?)
- List.Clear does work only if List is tagged?

-- 
RAPID maintainer
http://savannah.nongnu.org/projects/rapid/

^ permalink raw reply	[relevance 7%]

* Re: array from static predicate on enumerated type
  @ 2022-03-16  0:38  9%             ` Thomas
  0 siblings, 0 replies; 200+ results
From: Thomas @ 2022-03-16  0:38 UTC (permalink / raw)


In article <s2ofr1$1cg3$1@gioia.aioe.org>,
 "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote:

> On 2021-03-15 18:48, Shark8 wrote:
> 
> > So, in Ada, there's no good choice for how to actually DO an array with 
> > gaps in the index:
> 
> That applies to all containers. The problem is mapping the key to a 
> dense position when the key is not dense or might be unordered.
> 
> There is no gaps in positions.
> 
> > But Array *isn't* a map, though often it is substituted as one.
> 
> Of course it is, per definition of mapping. f : key -> element.
> 
> > Array has further constraints, like the contiguous memory labeled above.
> 
> No. The constraint here is a dense index. That is not specific to a 
> general map or an array. It is a fundamental property of the set of keys 
> being a convex set. Convex ensures certain useful mathematical 
> properties invariant to the representation of the mapping. In 
> particular, it gives a way to enumerate elements.

> Arbitrary predicate kills convex, so the problem. Not array. A map would 
> have just same problem: a map of LETTERS is in general not substitutable 
> for a map of CURVED_LETTERS.


i don't understand,
since Ada.Containers.Ordered_Maps.Key_Type is private,
and so new Ada.Containers.Ordered_Maps (CURVED_LETTERS, Integer) is 
allowed.

-- 
RAPID maintainer
http://savannah.nongnu.org/projects/rapid/

^ permalink raw reply	[relevance 9%]

* Re: Problem with emacs ada-mode-7.1.4
  2021-07-18 16:24  6%           ` Simon Wright
@ 2021-07-19 21:17  0%             ` Stephen Leake
  0 siblings, 0 replies; 200+ results
From: Stephen Leake @ 2021-07-19 21:17 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> Paul Onions <ponions37@gmail.com> writes:
>
>> I have one question: was my original problem a bug in the ada-mode
>> code or is it a bug in the latest GNAT compiler?  (GCC 11.1.0)
>
> Just had a poke around.
>
> GNAT CE 2019, using the matching gnatcoll-db and gnatcoll-bindings from
> the CE download site, worked OK.
>
> CE 2020, with its matching bindings, required the WORKAROUND changes to
> build.
>
> CE 2021, with its matching bindings, failed in *exactly the same way* as
> FSF GCC 11.1.0!! There was an interesting thread about this at [1]; I'm
> not sure from that whether the ada-mode code is OK or not, but it seems
> that even if it is we'll have to wait for a later compiler release.

I think the latest gnat compiler is more correct, so the bug is in the
ada-mode code. There is a fix in the devel version of ada-mode (it still
has workarounds for a remaining compiler bug I found while creating that
fix). 

I think you can access that devel version of ada-mode via the "bleeding
edge" elpa repository, which serves the HEAD versions instead of the
release versions. But I can't find any instructions on how to do that in
the ELPA docs.

> The lesson I'd draw is that building your own container collection is
> risky. 

More generally, trusting the compiler to check use of access types, by
never using 'Unchecked_Access.

> At least if you start from Ada.Containers you have a reasonably firm
> basis.

I question "firm"; they use 'Unchecked_Access internally, and they are
not written in Spark. The best you can say is "maintained by AdaCore",
which nominally means any bugs exposed by compiler updates are fixed
before the compiler updates are released.

I posit that I have more experience writing Ada code than many of the
people now at AdaCore :).

Some of the containers in ada-mode that are required to be fast (because
they are used a lot in error recovery) are written in Spark; they use
bounded data storage, not allocation. Some are not, because they require
allocation. Spark has lately added some support for allocation; I'll
have to check if that means I can now migrate those containers to Spark.

> With regard to "matching bindings" above, these can be found at the CE
> download site[2]. 

As you point out, that has gnatcoll-bindings, but not gnatcoll-db;
gnatcoll-db is only available via github. ada-mode.info currently says
to get gnatcoll-bindings from github; I'll change that.

A recent exchange with AdaCore indicated that packages on github are
_not_ supported (even with a support contract). Which I did not know
before, and is yet another reason to switch to libadalang (which is
supported).

-- 
-- Stephe

^ permalink raw reply	[relevance 0%]

* Re: Problem with emacs ada-mode-7.1.4
  @ 2021-07-18 16:24  6%           ` Simon Wright
  2021-07-19 21:17  0%             ` Stephen Leake
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2021-07-18 16:24 UTC (permalink / raw)


Paul Onions <ponions37@gmail.com> writes:

> I have one question: was my original problem a bug in the ada-mode
> code or is it a bug in the latest GNAT compiler?  (GCC 11.1.0)

Just had a poke around.

GNAT CE 2019, using the matching gnatcoll-db and gnatcoll-bindings from
the CE download site, worked OK.

CE 2020, with its matching bindings, required the WORKAROUND changes to
build.

CE 2021, with its matching bindings, failed in *exactly the same way* as
FSF GCC 11.1.0!! There was an interesting thread about this at [1]; I'm
not sure from that whether the ada-mode code is OK or not, but it seems
that even if it is we'll have to wait for a later compiler release.

The lesson I'd draw is that building your own container collection is
risky. At least if you start from Ada.Containers you have a reasonably
firm basis.

With regard to "matching bindings" above, these can be found at the CE
download site[2]. Find the compiler release you want the bindings for
(we Mac users are better off going for the x86 GNU Linux (64 bits)
version) and click on the Sources link. For CE 2021, you'll find -core
and -bindings but not -db; I see that I used the v21.0.0 tag from
AdaCore's github repo when I built the binary CE 2021 distribution
you'll find at [3].

[1]
https://groups.google.com/g/comp.lang.ada/c/7dw7Oqi8lIk/m/t6UJkTIHDQAJ
[2] https://www.adacore.com/download/more
[3] https://github.com/simonjwright/distributing-gcc/releases/tag/gnat-ce-2021

^ permalink raw reply	[relevance 6%]

* Re: GCC 11 bug? lawyer needed
  2021-05-06 20:02  9%         ` Simon Wright
  2021-05-06 20:51  0%           ` Dmitry A. Kazakov
@ 2021-05-06 23:59  0%           ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Randy Brukardt @ 2021-05-06 23:59 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message 
news:lylf8ry6j5.fsf@pushface.org...
> "Randy Brukardt" <randy@rrsoftware.com> writes:
>
>> I agree that the original author of that program should not have used
>> "aliased" in the way that they did (they don't need the special 
>> semantics),
>> but we realize that some people would prefer to *explicitly* mark things 
>> as
>> aliased when they are going to take 'Access (and not worry about the type 
>> of
>> the parameter -- after all, it could change). That is, they don't want to
>> depend on the implicit behavior of tagged types -- or perhaps they don't
>> even know about it. Which leads to the problem that occurs here, as
>> "aliased" has slightly different meanings for functions (now just 
>> composite
>> functions) and procedures.
>
> The original code, from the Alire project, had (I've edited it slightly)
>
>   package Holders
>   is new Ada.Containers.Indefinite_Holders (Node'Class);
>
>   type Tree is
>     new Holders.Holder
>     and ...
>
>   function Root (This : Tree) return Node'Class is
>     (This.Constant_Reference);
>
> where that Constant_Reference is inherited (eventually) from
> Ada.Containers.Indefinite_Holders.Holder,
>
>   function Constant_Reference
>     (Container : aliased Holder) return Constant_Reference_Type;
>   pragma Inline (Constant_Reference);
>
> Shame it had to be there.

Constant_Reference is the case for which these semantics was designed. Hard 
to avoid it there. ;-)

Note that by returning Node'Class rather than an elementary type, you don't 
get to use the new rule tweak. Since all tagged types are by-reference (not 
by copy), the "Root" routine has to return the object that it has, which 
ultimately is part of Tree. So you actually need "aliased" on Root, since 
you are (ultimately) returning a part of the formal parameter (and which 
could become dangling if you pass in an object which is too local).

> I've just tried splattering 'aliased' wherever the compiler told me it
> was needed; it's now spreading into other packages. Ugh.

I think you need to make a copy of the return object somewhere; the obvious 
answer is to replace function Constant_Reference with function Element. Of 
course, if the return object is large enough, that could be expensive. (That 
doesn't work if you want to write the node, but the use of 
Constant_Reference doesn't allow that anyway, so in this case it doesn't 
matter.)

> The solution might just be using composition rather than inheritance.

Yeah, or using handles more as Dmitry says. In any case, it seems like some 
redesign is necessary.

                  Randy.


^ permalink raw reply	[relevance 0%]

* Re: GCC 11 bug? lawyer needed
  2021-05-06 20:02  9%         ` Simon Wright
@ 2021-05-06 20:51  0%           ` Dmitry A. Kazakov
  2021-05-06 23:59  0%           ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2021-05-06 20:51 UTC (permalink / raw)


On 2021-05-06 22:02, Simon Wright wrote:
> "Randy Brukardt" <randy@rrsoftware.com> writes:
> 
>> I agree that the original author of that program should not have used
>> "aliased" in the way that they did (they don't need the special semantics),
>> but we realize that some people would prefer to *explicitly* mark things as
>> aliased when they are going to take 'Access (and not worry about the type of
>> the parameter -- after all, it could change). That is, they don't want to
>> depend on the implicit behavior of tagged types -- or perhaps they don't
>> even know about it. Which leads to the problem that occurs here, as
>> "aliased" has slightly different meanings for functions (now just composite
>> functions) and procedures.
> 
> The original code, from the Alire project, had (I've edited it slightly)
> 
>     package Holders
>     is new Ada.Containers.Indefinite_Holders (Node'Class);
> 
>     type Tree is
>       new Holders.Holder
>       and ...
> 
>     function Root (This : Tree) return Node'Class is
>       (This.Constant_Reference);
> 
> where that Constant_Reference is inherited (eventually) from
> Ada.Containers.Indefinite_Holders.Holder,
> 
>     function Constant_Reference
>       (Container : aliased Holder) return Constant_Reference_Type;
>     pragma Inline (Constant_Reference);
> 
> Shame it had to be there.
> 
> I've just tried splattering 'aliased' wherever the compiler told me it
> was needed; it's now spreading into other packages. Ugh.
> 
> The solution might just be using composition rather than inheritance.

In my experience mixing handles with target types does not work anyway 
regardless accessibility rules mess.

I tend to use interfaces instead:

    type Abstract_Node_Interface is interface ...;

Then both the handle and the target type implement 
Abstract_Node_Interface. The target type goes into hiding, the client 
need not to see it.

This requires manual delegation in all primitive operations of handles: 
dereference + call. But in the end it pays off. Especially with trees, 
because in mutator operations I can check the reference count of the 
node and choose to clone it (and maybe the subtree) if there are 
multiple external handles to it.

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

^ permalink raw reply	[relevance 0%]

* Re: GCC 11 bug? lawyer needed
  @ 2021-05-06 20:02  9%         ` Simon Wright
  2021-05-06 20:51  0%           ` Dmitry A. Kazakov
  2021-05-06 23:59  0%           ` Randy Brukardt
  0 siblings, 2 replies; 200+ results
From: Simon Wright @ 2021-05-06 20:02 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> I agree that the original author of that program should not have used 
> "aliased" in the way that they did (they don't need the special semantics), 
> but we realize that some people would prefer to *explicitly* mark things as 
> aliased when they are going to take 'Access (and not worry about the type of 
> the parameter -- after all, it could change). That is, they don't want to 
> depend on the implicit behavior of tagged types -- or perhaps they don't 
> even know about it. Which leads to the problem that occurs here, as 
> "aliased" has slightly different meanings for functions (now just composite 
> functions) and procedures.

The original code, from the Alire project, had (I've edited it slightly)

   package Holders
   is new Ada.Containers.Indefinite_Holders (Node'Class);

   type Tree is
     new Holders.Holder
     and ...

   function Root (This : Tree) return Node'Class is
     (This.Constant_Reference);

where that Constant_Reference is inherited (eventually) from
Ada.Containers.Indefinite_Holders.Holder,

   function Constant_Reference
     (Container : aliased Holder) return Constant_Reference_Type;
   pragma Inline (Constant_Reference);

Shame it had to be there.

I've just tried splattering 'aliased' wherever the compiler told me it
was needed; it's now spreading into other packages. Ugh.

The solution might just be using composition rather than inheritance.

^ permalink raw reply	[relevance 9%]

* Re: array from static predicate on enumerated type
  @ 2021-03-15 17:53  7%         ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2021-03-15 17:53 UTC (permalink / raw)


On Monday, March 15, 2021 at 8:16:58 AM UTC-6, Matt Borchers wrote:
> On Friday, March 12, 2021 at 11:55:54 PM UTC-5, Randy Brukardt wrote: 
> > Just don't use them with obsolete data structures. :-)
> I can't tell if you are you being facetious? If not, can you give me some reasons on why you think arrays are obsolete data structures? To me, they remain one of the basic building blocks of all programs.
They are a basic building-block, yes.
But they *AREN'T* maps, nor are they functions... despite the tendency to think of them as nails for your hammer (Array), this really isn't the case... and now that Ada has Ada.Containers.Indefinite_Ordered_Maps it really is an obsolete data-structure for mapping in most cases. (Exceptions exist for things like finite-state machines and virtual-machine instruction-sets where you're working with a uniform/near-uniform collection and/or things like embedded.)

^ permalink raw reply	[relevance 7%]

* Re: rr
  @ 2021-03-04 22:48  7%               ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2021-03-04 22:48 UTC (permalink / raw)


Emmanuel Briot <briot.emmanuel@gmail.com> writes:

>> It'd probably really help with my current problem, where GCC 11.0.0 and 
>> GNAT CE 2020 arm-eabi throw an ICE when compiling a generalised 
>> iteration
>
> Might be unrelated, but: we have noticed recently that a generalized
> iteration ("for..of") was wrongly calling `activate_task`. In
> particular, this resulted in errors when executing such loops from a
> protected object and enabling the checks that no potentially blocking
> operation is executed in such contexts.
>
> We reported this to AdaCore who fixed it in their more recent
> wavefronts. I am not sure when the
> error started to occur though, so maybe not that helpful to you :-)

I reported this, and Eric has come up with the goods! We're at 11.0.1
now (how can you tell what release ID a particular GCC commit will
produce?), so there's a good chance it'll make it into the 11.1.0
release.

Not that there are likely to be loads of people around making RTSs with
Ada.Containers for MCUs. The issue didn't cause problems with AdaCore's
ravenscar-full-stm32f4.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99360

^ permalink raw reply	[relevance 7%]

* Re: set_index and and end_of_file with just a stream reference
  @ 2021-02-23 17:21  8%           ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2021-02-23 17:21 UTC (permalink / raw)


On Saturday, February 20, 2021 at 12:08:16 PM UTC-7, 0012com wrote:
> Okay :-) 
> what I wanted is: 
> I read an acronyme in the stream file, if good I input the adjacent record type, otherwise I would advance on the stream until the next acronyme with set_index(stream_access, index(stream_access) + composite_type_stream_size) and read the next acronyme (unbounded_string). 
> Now I just input both objects and verify the acronyme. 
> But I don't like writing an object that maybe won't be used.
Hm, what are your datatypes? Is this ONLY text, or are you able to impose your own structure?
You could have something like this:

-- Instantiated Container Packages.
Package String_Holder is new Ada.Containers.Indefinite_Holders(
       Element_Type => String,
       "="          => Ada.Strings.Equal_Case_Insensitive
      );
Package String_Map is new Ada.Containers.Indefinite_Ordered_Maps(
       "<"          => Ada.Strings.Less_Case_Insensitive,
       "="          => Ada.Strings.Equal_Case_Insensitive,
       Key_Type     => String,
       Element_Type => String
      );

-- The heart of the operating program.
With String_Holder, String_Map;
Package Acronyms is
  -- Because this is it's own type, you can put other things in the record, like a link to the place that it's defined, if needed.
  Type Initialism is new String_Holder.Holder with null record;

  Function Expand( Acronym : Initialism ) return String;
  Procedure Register( Acronym, Expansion : String );
--...
End Acronyms;

Package Body Acronyms is
    Acronym_Map : String_Map.Map;
  Procedure Register( Acronym, Expansion : String ) is
  Begin
    Acronym_Map.Insert( New_Item => Expansion, Key => Acronym );
  End Register;  

  Function Expand( Acronym : Initialism ) return String is
  Begin
    Return Acronym_Map( Acronym );
  Exception
    when others => Return Acronym; -- I forget if it's CONSTRAINT_ERROR or ASSERT_ERROR when the element is not present.
  End Expand;
End Acronyms;

-- in your main Acronym-Stream package...
-- Text_Soup is a variant record for handling portions of an acronym-expanding string; your main data-structure would probably be an Indefinite_Vector of Text_Soup'Class,
-- you might not need Input or output, depending on your usage, but for automatically expanding the initialism you'd need to use Acronyms.Expand.

    Type Text_Soup(<>) is tagged private;
    procedure Output(
       Stream : not null access Ada.Streams.Root_Stream_Type'Class;
       Item   : in Text_Soup'Class);
    function Input(
       Stream : not null access Ada.Streams.Root_Stream_Type'Class)
       return Text_Soup'Class;

   -- Other public operations.
PRIVATE
    For Text_Soup'Class'Input  use Input;
    For Text_Soup'Class'Output use Output;

Type Text_Soup(Length : Natural) is record
  case Length is
    when 0 => Acronym : Initialism;
    when others => Text : String(1..Length);
  end case;
end record;
--...


^ permalink raw reply	[relevance 8%]

* Re: specifying only 'First of an index in an array
  @ 2021-02-03 19:29  7% ` Jeffrey R. Carter
  0 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2021-02-03 19:29 UTC (permalink / raw)


On 2/3/21 6:47 PM, Mehdi Saada wrote:
> Is there a way, on nominal or genetic array type definition (I mean in generic specifications), to ensure that Index_type'First is always the same, but that arrays can still grow ?

Arrays can't grow in Ada, so I don't know what you're asking. For a sequence 
with a fixed lower bound and variable length you can use Ada.Containers.Vectors.

-- 
Jeff Carter
"Sheriff murdered, crops burned, stores looted,
people stampeded, and cattle raped."
Blazing Saddles
35

^ permalink raw reply	[relevance 7%]

* Re: Lower bounds of Strings
  @ 2021-01-09 10:53  6%                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2021-01-09 10:53 UTC (permalink / raw)


On 2021-01-09 03:18, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:rtaeok$l8b$1@gioia.aioe.org...
>> On 2021-01-08 18:23, Shark8 wrote:
>>> On Thursday, January 7, 2021 at 3:03:54 PM UTC-7, Randy Brukardt wrote:
>>
>>>> Any sort of multiple inheritance (not to mention multiple dispatch)
>>>> requires
>>>> searching a lookup table for the appropriate interface.
>>> Ah.
>>> It appears you're confusing the Ada concept underlying keyword INTERFACE
>>> with the general/abstract notion.
>>> It appears to me that Dmitry is referring to the latter, not the
>>> Ada-construct of INTERFACE, which requires a tagged type.
>>>
>>> I think what he's getting at is something that I considered/proposed here
>>> on C.L.A some years ago, adding the concept of an "ABSTRACT INTERFACE" to
>>> Ada. (IIRC, the proposal I had in mind was to be able to model the
>>> notional meta type-hierarchy; eg: Number ? Universal_Integer ?
>>> System.Integer.)
>>
>> Right, though I do not think that tags can inflict any cost. The situation
>> is same as with array bounds. You do keep bounds when the array is
>> statically constrained. Tag is just another constraint like bounds. It
>> must be handled just same way, removed when statically known. No penalty,
>> unless classes are actually used. I do not know why people always bring
>> dispatch into discussions about static cases.
> 
> The possibility of dynamic dispatch (in some code that doesn't exist yet,
> but *could*) is what is so expensive and is virtually impossible to remove
> after the fact (that is, in an optimizer).

The representation without the tag must be mandatory.

> If you wanted to include a
> declaration that you *never* were going to use any dynamic dispatch,

This declaration is already in the language. Only A'Class dispatches. 
Again, it is like with bounds, only array (... range <>) of ... has 
dynamic bounds. To enforce dispatch one would have to convert to A'Class 
first, that will add the tag to the array's dope vector.

> then
> you could talk try to ignore the possibility. But without some sort of
> dispatch, a defined interface buys you nothing other than complication. It
> doesn't simplify the description and would substantially complicate the
> implementation. What's the point??

Of course it will simplify everything. E.g. our beloved generics. Compare

    generic
       type I is (<>);
       type E is private;
       type A is array (I range <>) of E;

with

    generic
       type A is new Root_Array_Type with private;

or

    package Ada.Containers.Vectors is
       ...
       type Vector is tagged private
          with Constant_Indexing => Constant_Reference,
               Variable_Indexing => Reference,
               Default_Iterator  => Iterate,
               Iterator_Element  => Element_Type;
       -- hundreds of operation declarations

with

    type Vector is new array (Index_Type) of Element_Type with private;
       -- nothing else to declare

Everything in Ada could be formalized in interfaces:

   type Index is new Discrete_Type; -- Same as <>
   type Discrete_Type is abstract new Ordered_Type and Copyable_Type;

and so on.

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

^ permalink raw reply	[relevance 6%]

* Re: Lower bounds of Strings
  2021-01-07  0:17  8%     ` Randy Brukardt
@ 2021-01-07  9:57  0%       ` Dmitry A. Kazakov
    0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2021-01-07  9:57 UTC (permalink / raw)


On 2021-01-07 01:17, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:rt3uv2$1nrd$1@gioia.aioe.org...
>> On 2021-01-06 04:08, Randy Brukardt wrote:
>>> IMHO, "String" shouldn't be an array at all. In a UTF-8 world, it makes
>>> little sense to index into a string - it would be expensive to do it
>>> based
>>> on characters (since they vary in size), and dangerous to do it based on
>>> octets (since you could get part of a character).
>>
>> It will not work. There is no useful integral operations defined on
>> strings. It is like arguing that image is not an array of pixels because
>> you could distort objects in there when altering individual pixels.
>>
>>> The only real solution is to never use String in the first place. A
>>> number
>>> of people are building UTF-8 abstractions to replace String, and I expect
>>> those to become common in the coming years.
>>
>> This will never happen. Ada standard library already has lots of integral
>> operations defined on strings. They are practically never used. The UTF-8
>> (or whatever encoding) abstraction thing simply does not exist.
>>
>>> Indeed, (as I've mentioned before) I would go further and abandon arrays
>>> altogether -- containers cover the same ground (or could easily) -- the
>>> vast
>>> complication of operators popping up much after type declarations,
>>> assignable slices, and supernull arrays all waste resources and cause
>>> oddities and dangers. It's a waste of time to fix arrays in Ada -- just
>>> don't use them.
>>
>> How these containers are supposed to be implemented?
> 
> Built-in to the implementation, of course. Implementing these things in Ada
> is a nice capability, because that allows simple quick-and-dirty
> implementations. But for things that are commonly used, that necessarily
> leads to lousy performance. One has to have at least some special cases even
> for the Ada.Containers to get adequate performance, so there's no problem
> extending that.

OK, they cannot be implemented in this new Ada. How is that different to 
the present status? Drop features and make syntax ugly is that all?

> ...
>> How Stream_Element_Array is supposed to be an opaque container?
> 
> It should already be an opaque container. You use language-defined stream
> attributes to implement user-defined stream attributes - not unportable
> direct byte twiddling.

No, you are talking about stream here, I am about Stream_Element_Array.

>> How file read operation is supposed to assign part of a container?
> 
> ??? Why would you want to do that?

Well, to read a chuck of data from the socket. Where it goes?

> Streaming a bounded vector (which almost
> all existing arrays should be) naturally would read only the active part of
> the vector.

What is active part of vector? Does it have some type? How do I pass it 
to a subprogram?

> Non-streaming reading is left over Ada 83 nonsense; all I/O
> should be built on top of streams (as a practical matter, the vast majority
> is anyway).

No physical I/O is stream with very rare exceptions.

>> You cannot rid of array interface with all its types involved: index,
>> index set (range), element, element set (array). A containers without the
>> array interface cannot replace array. Any language must support them. The
>> problem is that Ada has array interfaces once built-in and as an ugly lame
>> monstrosity of helper tagged types, a mockery of array.
> 
> There no reason that a container interface cannot have those things --
> Ada.Containers.Vectors does.

As array it is unusable.

> The things that Vectors is missing (mainly the
> ability to use enumeration and modular indexes) was a mistake that I
> complained about repeatedly during the design, but I lost on that.

It has all disadvantages of being no array and no advantages of being a 
tagged type. I do not see how two bad could make one good.

>> Array implementation is a fundamental building block of computing.
> 
> Surely. But one does not need the nonsense of requiring an underlying
> implementation (which traditional arrays do) in order to get that building
> block. You always talk about this in terms of an "interface", which is
> essentially the same idea. One cannot have any sort of non-contigious or
> persistent arrays with the Ada interface, since operations like assigning
> into slices are impossible in such representations. One has to give those
> things up in order to have an "interface" rather than the concrete form for
> Ada arrays.

No, one should have interfaces for such operations as well. You cannot 
do that with a single type and single dispatch. That is another reason 
why you cannot replace built-in arrays with anything before you resolve 
the type system issues. The elephant is the room is that you cannot 
spell array type in Ada. So your solution is supposed to be let's have 
no arrays. That is no solution at all.

> I prefer to not call the result an array, since an array implies a
> contiguous in-memory representation. Of course, some vectors will have such
> a representation, but that needs to be a requirement only for vectors used
> for interfacing. (And those should be used rarely.)

And how these special vectors will differ from other vectors? If Read 
takes special vector (does it?) can I pass a non-special vector instead? 
It leaks. Ada 83 resolved all this per compiler magic. Modern Ada has 
nothing more to offer.

>> That does not go either. Of course you could have two languages, one with
>> arrays to implement containers and one without them for end users. But
>> this is neither Ada philosophy nor a concept for any good
>> universal-purpose language.
> 
> Compilers implement arrays in Ada; there is no possibility a user doing it.
> I see no difference between that and having the compiler implement a bounded
> vector instead as the fundamental building block.

See above. Is bounded vector a vector? No, you cannot make it. So you 
are right back with ugly half-baked arrays named bounded vectors and 
even uglier unbounded vectors with zillion generic functions to convert 
one to another.

> You seem fixated on the
> form of declaration (that is a generic package vs. some sort of built-in
> syntax) -- there's no fundamental difference.

If syntax were the only problem it would be easy to resolve by adding it 
to generics. The problem is not syntax but lacking functionality and 
types and subtypes involved. Generics simply cannot do anything 
resembling Ada 83 arrays.

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

^ permalink raw reply	[relevance 0%]

* Re: Lower bounds of Strings
  @ 2021-01-07  0:17  8%     ` Randy Brukardt
  2021-01-07  9:57  0%       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2021-01-07  0:17 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:rt3uv2$1nrd$1@gioia.aioe.org...
> On 2021-01-06 04:08, Randy Brukardt wrote:
>> IMHO, "String" shouldn't be an array at all. In a UTF-8 world, it makes
>> little sense to index into a string - it would be expensive to do it 
>> based
>> on characters (since they vary in size), and dangerous to do it based on
>> octets (since you could get part of a character).
>
> It will not work. There is no useful integral operations defined on 
> strings. It is like arguing that image is not an array of pixels because 
> you could distort objects in there when altering individual pixels.
>
>> The only real solution is to never use String in the first place. A 
>> number
>> of people are building UTF-8 abstractions to replace String, and I expect
>> those to become common in the coming years.
>
> This will never happen. Ada standard library already has lots of integral 
> operations defined on strings. They are practically never used. The UTF-8 
> (or whatever encoding) abstraction thing simply does not exist.
>
>> Indeed, (as I've mentioned before) I would go further and abandon arrays
>> altogether -- containers cover the same ground (or could easily) -- the 
>> vast
>> complication of operators popping up much after type declarations,
>> assignable slices, and supernull arrays all waste resources and cause
>> oddities and dangers. It's a waste of time to fix arrays in Ada -- just
>> don't use them.
>
> How these containers are supposed to be implemented?

Built-in to the implementation, of course. Implementing these things in Ada 
is a nice capability, because that allows simple quick-and-dirty 
implementations. But for things that are commonly used, that necessarily 
leads to lousy performance. One has to have at least some special cases even 
for the Ada.Containers to get adequate performance, so there's no problem 
extending that.

...
> How Stream_Element_Array is supposed to be an opaque container?

It should already be an opaque container. You use language-defined stream 
attributes to implement user-defined stream attributes - not unportable 
direct byte twiddling.

> How file read operation is supposed to assign part of a container?

??? Why would you want to do that? Streaming a bounded vector (which almost 
all existing arrays should be) naturally would read only the active part of 
the vector. Non-streaming reading is left over Ada 83 nonsense; all I/O 
should be built on top of streams (as a practical matter, the vast majority 
is anyway).

> You cannot rid of array interface with all its types involved: index, 
> index set (range), element, element set (array). A containers without the 
> array interface cannot replace array. Any language must support them. The 
> problem is that Ada has array interfaces once built-in and as an ugly lame 
> monstrosity of helper tagged types, a mockery of array.

There no reason that a container interface cannot have those things --  
Ada.Containers.Vectors does. The things that Vectors is missing (mainly the 
ability to use enumeration and modular indexes) was a mistake that I 
complained about repeatedly during the design, but I lost on that.

> Array implementation is a fundamental building block of computing.

Surely. But one does not need the nonsense of requiring an underlying 
implementation (which traditional arrays do) in order to get that building 
block. You always talk about this in terms of an "interface", which is 
essentially the same idea. One cannot have any sort of non-contigious or 
persistent arrays with the Ada interface, since operations like assigning 
into slices are impossible in such representations. One has to give those 
things up in order to have an "interface" rather than the concrete form for 
Ada arrays.

I prefer to not call the result an array, since an array implies a 
contiguous in-memory representation. Of course, some vectors will have such 
a representation, but that needs to be a requirement only for vectors used 
for interfacing. (And those should be used rarely.)

> That does not go either. Of course you could have two languages, one with 
> arrays to implement containers and one without them for end users. But 
> this is neither Ada philosophy nor a concept for any good 
> universal-purpose language.

Compilers implement arrays in Ada; there is no possibility a user doing it. 
I see no difference between that and having the compiler implement a bounded 
vector instead as the fundamental building block. You seem fixated on the 
form of declaration (that is a generic package vs. some sort of built-in 
syntax) -- there's no fundamental difference. There are many Ada packages 
that are built-in to compilers (for Janus/Ada, these include System and 
Ada.Exceptions and Ada.Assertions) -- there's no body or even source of 
these to be seen.

We're not even talking about different syntax for the use of vectors (and it 
would be easy to have some syntax sugar for declarations - we already have a 
proposal on those lines for Ada). Indeed, in a new language, one would 
certainly call these "array" containers (couldn't do that in Ada as the word 
"array" is reserved).

Sometimes, one has to step back and look at the bigger picture and not 
always at the way things have always been done. Arrays (at least as defined 
in Ada) have outlived their usefulness.

                          Randy.




^ permalink raw reply	[relevance 8%]

* Re: Advent of Code day 5
  2020-12-06 21:09  7%       ` Björn Lundin
@ 2020-12-09  1:18  0%         ` Stephen Leake
  0 siblings, 0 replies; 200+ results
From: Stephen Leake @ 2020-12-09  1:18 UTC (permalink / raw)


Björn Lundin <b.f.lundin@gmail.com> writes:

> Den 2020-12-06 kl. 17:21, skrev Stephen Leake:
>> I didn't bother computing row and seat, since they are not actually
>> needed to find the answer.
>> 
>>> and ran it through cut/sort/uniq
>> Next time, try ada.containers.generic_array_sort;
>> http://www.ada-auth.org/standards/2xrm/html/RM-A-18-26.html
>
> So I was thinking -should I do this the 'proper' way - only use a
> language, or should I use whatever tool that makes it quickest, since 
> only a number was the final answer.

For the actual competition, any tool that works for you is fine; there
is no restriction to "use only this language".

But some people are doing this as a mechanism to learn Ada, so I'm using
your example to tell them about how to do this in Ada instead of Bash.

In day 7, I'm using WisiToken, which is an Ada parsing library I maintain.
I'm following the rule "use any Ada library available on the web".

-- 
-- Stephe

^ permalink raw reply	[relevance 0%]

* Re: Advent of Code day 5
  2020-12-06 16:21  7%     ` Stephen Leake
  2020-12-06 16:27  0%       ` Stephen Leake
@ 2020-12-06 21:09  7%       ` Björn Lundin
  2020-12-09  1:18  0%         ` Stephen Leake
  1 sibling, 1 reply; 200+ results
From: Björn Lundin @ 2020-12-06 21:09 UTC (permalink / raw)


Den 2020-12-06 kl. 17:21, skrev Stephen Leake:
> I didn't bother computing row and seat, since they are not actually
> needed to find the answer.
> 
>> and ran it through cut/sort/uniq
> Next time, try ada.containers.generic_array_sort;
> http://www.ada-auth.org/standards/2xrm/html/RM-A-18-26.html

So I was thinking -should I do this the 'proper' way - only use a 
language, or should I use whatever tool that makes it quickest, since 
only a number was the final answer.

This way, I did it quicker than implementing all if it in ada,
and I got a good grip of what was happening, by adding the pipes  one by 
one.

This is of course why I posted. Sometimes a combination of tools
gets you (or actually me) faster to the goal.

I haven't used generic_arrray_sort much, but I've done quite some
sorting on Ada.Containers.Doubly_linked_Lists - and I think they are 
close in howto use. But - I think those external tools were faster for me.


-- 
Björn

^ permalink raw reply	[relevance 7%]

* Re: Advent of Code Day 6
  2020-12-06 11:07  7% ` Jeffrey R. Carter
@ 2020-12-06 19:37  9%   ` John Perry
  0 siblings, 0 replies; 200+ results
From: John Perry @ 2020-12-06 19:37 UTC (permalink / raw)


On Sunday, December 6, 2020 at 5:07:24 AM UTC-6, Jeffrey R. Carter wrote:
> On 12/6/20 9:39 AM, John Perry wrote: 
> >...the only way I could find to count the number of elements in a Character_Set was by converting it to a Character_Sequence. Is there another way?
> Probably one of the set pkgs in Ada.Containers or 
> PragmARC.Data_Structures.Sets.Discrete might be a better choice than Character_Set 

Thanks, Ada.Containers.Hashed_Sets works fine. I look forward to initialization of containers in the next edition of gnat.

john perry

^ permalink raw reply	[relevance 9%]

* Re: Advent of Code day 5
  2020-12-06 16:21  7%     ` Stephen Leake
@ 2020-12-06 16:27  0%       ` Stephen Leake
  2020-12-06 21:09  7%       ` Björn Lundin
  1 sibling, 0 replies; 200+ results
From: Stephen Leake @ 2020-12-06 16:27 UTC (permalink / raw)


Stephen Leake <stephen_leake@stephe-leake.org> writes:

> Next time, try ada.containers.generic_array_sort;
> http://www.ada-auth.org/standards/2xrm/html/RM-A-18-26.html

Or Doubly_Linked_Lists.Generic_Sorting:

http://www.ada-auth.org/standards/2xrm/html/RM-A-18-3.html

--
-- Stephe

^ permalink raw reply	[relevance 0%]

* Re: Advent of Code day 5
  @ 2020-12-06 16:21  7%     ` Stephen Leake
  2020-12-06 16:27  0%       ` Stephen Leake
  2020-12-06 21:09  7%       ` Björn Lundin
  0 siblings, 2 replies; 200+ results
From: Stephen Leake @ 2020-12-06 16:21 UTC (permalink / raw)


Björn Lundin <b.f.lundin@gmail.com> writes:

> Den 2020-12-06 kl. 10:14, skrev Jeffrey R. Carter:
>> On 12/5/20 3:54 PM, Stephen Leake wrote:
>>> that was trivial
>> I'm curious: Did everyone do this by treating the input as a coded 
>> 10-digit binary number, or did some take another approach?
>> 
>
>
> I uses it as binary 7 +3, but I did the calculaions through the shell
> text utilities
>
>
> First I decoded and printed all rows, seats and ids like
>
> loop file and decode
>   ...
>   Text_Io.Put_Line (Row'Img & Seat'Img & Id'Img);
> end loop

I didn't bother computing row and seat, since they are not actually
needed to find the answer.

> and ran it through cut/sort/uniq

Next time, try ada.containers.generic_array_sort;
http://www.ada-auth.org/standards/2xrm/html/RM-A-18-26.html

I used a boolean array to do the sort:

   declare
      Present : array (Integer range 1 .. Max_ID) of Boolean := (others => False);
   begin
      for ID of IDs loop
         Present (ID) := True;
      end loop;

      for ID in Present'First + 1 .. Present'Last - 1 loop
         if Present (ID - 1) and (not Present (ID)) and Present (ID + 1) then
            Put_Line ("my seat id:" & ID'Image);
         end if;
      end loop;
   end;

-- 
-- Stephe

^ permalink raw reply	[relevance 7%]

* Re: Advent of Code Day 6
  @ 2020-12-06 11:07  7% ` Jeffrey R. Carter
  2020-12-06 19:37  9%   ` John Perry
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2020-12-06 11:07 UTC (permalink / raw)


On 12/6/20 9:39 AM, John Perry wrote:
> Today was quite easy, so I used the opportunity to learn about Ada.Strings.Maps, and that made for a much simpler solution to look at.
> 
> I do wonder about the efficiency, though. For instance, the only way I could find to count the number of elements in a Character_Set was by converting it to a Character_Sequence. Is there another way?

Probably one of the set pkgs in Ada.Containers or 
PragmARC.Data_Structures.Sets.Discrete might be a better choice than Character_Set

-- 
Jeff Carter
“[T]here are lots of people out there writing software
that should really be out cleaning toilets instead.”
Brian Catlin
173

^ permalink raw reply	[relevance 7%]

* Re: Dueling Compilers
  2020-11-25 14:08 10% Dueling Compilers Jeffrey R. Carter
  2020-11-26  2:19  0% ` Randy Brukardt
@ 2020-12-02 15:41  0% ` Shark8
  1 sibling, 0 replies; 200+ results
From: Shark8 @ 2020-12-02 15:41 UTC (permalink / raw)


On Wednesday, November 25, 2020 at 7:08:43 AM UTC-7, Jeffrey R. Carter wrote:
> Consider the package 
> 
> with Ada.Containers.Bounded_Doubly_Linked_Lists; 
> 
> generic 
> type E is private; 
> package Preelaborable is 
> package EL is new Ada.Containers.Bounded_Doubly_Linked_Lists 
> (Element_Type => E); 
> end Preelaborable; 
> 
> Two Ada-12 compilers give different results on this. Compiler G accepts it 
> without problem. Compiler O rejects it with the error message 
> 
> preelaborable.ads: Error: line 6 col82 LRM:10.2.1(11.8/2), If a pragma 
> Preelaborable_Initialization has been applied to the generic formal, the 
> corresponding actual type must have preelaborable initialization 
> 
> AFAICT from the ARM, the generic formal Element_Type of 
> Ada.Containers.Bounded_Doubly_Linked_Lists does not have pragma 
> Preelaborable_Initialization applied to it. However, the type List, which 
> probably has [sub]components of Element_Type, does. 
> 
> Which compiler is correct? What is the intent of the ARM? 

Acceptance is the correct evaluation.
"package NAME is" is quite clearly the proper construction, there is no aspect here, and so aspect "preelaborable" is *NOT* indicated, EVEN IF the given NAME is "preelaborable".

^ permalink raw reply	[relevance 0%]

* Re: Dueling Compilers
  2020-11-25 14:08 10% Dueling Compilers Jeffrey R. Carter
@ 2020-11-26  2:19  0% ` Randy Brukardt
  2020-12-02 15:41  0% ` Shark8
  1 sibling, 0 replies; 200+ results
From: Randy Brukardt @ 2020-11-26  2:19 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:rploh9$3kd$1@dont-email.me...
> Consider the package
>
> with Ada.Containers.Bounded_Doubly_Linked_Lists;
>
> generic
>    type E is private;
> package Preelaborable is
>    package EL is new Ada.Containers.Bounded_Doubly_Linked_Lists
>       (Element_Type => E);
> end Preelaborable;
>
> Two Ada-12 compilers give different results on this. Compiler G accepts it 
> without problem. Compiler O rejects it with the error message
>
> preelaborable.ads: Error: line 6 col82 LRM:10.2.1(11.8/2), If a pragma 
> Preelaborable_Initialization has been applied to the generic formal, the 
> corresponding actual type must have preelaborable initialization
>
> AFAICT from the ARM, the generic formal Element_Type of 
> Ada.Containers.Bounded_Doubly_Linked_Lists does not have pragma 
> Preelaborable_Initialization applied to it. However, the type List, which 
> probably has [sub]components of Element_Type, does.
>
> Which compiler is correct? What is the intent of the ARM?

I'd say both compilers are wrong, in that the RM clearly has a bug here and 
one of the implementers should have complained about it to the ARG long ago. 
:-) I'd suggest you post this question to Ada-Comment so that it gets on the 
ARG's radar.

(I'll call Preelaborable_Initialization "PI" in the following for my sanity. 
:-)

It's clear from 10.2.1 that a type with pragma PI which has components of a 
generic formal type has to have components that have a type with PI. It 
isn't possible to initialize such components without a function call, so the 
other possibility does not exist. The Bounded containers are designed such 
that there are components of the element type (more accurately, a component 
of an array of the element type). In order for there to be such a component, 
the formal type must have PI. Ergo, any body for a bounded container written 
in Ada is necessarily illegal. This is a problem that someone should have 
brought up at the ARG.

Since it is not required to write language-defined package bodies in Ada, 
one could imagine that both compilers are correct in the sense that they are 
using some non-Ada language to implement the containers. But that is is a 
fiction in the case of the containers (every implementation I know of is in 
Ada), and in any case, we intended the containers to be implementable in 
Ada. If they are not, that is a bug.

I don't know what the fix ought to be: adding PI to the formal private type 
would work, but it would reduce the usabibility of the containers in 
non-preelaborated contexts. Similarly, removing the PI from the container 
would work, but would reduce the usability of the containers in 
preelaborated contexts. Both seem pretty bad.

I'd be in favor of removing PI and Preelaboration in general from the 
language (it serves no purpose other than to encourage implementers to make 
optimizations that they should make anyway - the other intentions don't work 
or are better handled with other mechanisms), but I doubt that I'd get any 
support for that.

So this will have to be an ARG question -- I can't answer it definitively.

                                 Randy.

P.S. If you post this question to Ada-Comment, do me a favor and post this 
analysis along with it. That will save me having to reproduce it later.


^ permalink raw reply	[relevance 0%]

* Dueling Compilers
@ 2020-11-25 14:08 10% Jeffrey R. Carter
  2020-11-26  2:19  0% ` Randy Brukardt
  2020-12-02 15:41  0% ` Shark8
  0 siblings, 2 replies; 200+ results
From: Jeffrey R. Carter @ 2020-11-25 14:08 UTC (permalink / raw)


Consider the package

with Ada.Containers.Bounded_Doubly_Linked_Lists;

generic
    type E is private;
package Preelaborable is
    package EL is new Ada.Containers.Bounded_Doubly_Linked_Lists
       (Element_Type => E);
end Preelaborable;

Two Ada-12 compilers give different results on this. Compiler G accepts it 
without problem. Compiler O rejects it with the error message

preelaborable.ads: Error: line 6 col82 LRM:10.2.1(11.8/2), If a pragma 
Preelaborable_Initialization has been applied to the generic formal, the 
corresponding actual type must have preelaborable initialization

AFAICT from the ARM, the generic formal Element_Type of 
Ada.Containers.Bounded_Doubly_Linked_Lists does not have pragma 
Preelaborable_Initialization applied to it. However, the type List, which 
probably has [sub]components of Element_Type, does.

Which compiler is correct? What is the intent of the ARM?

-- 
Jeff Carter
"Apart from the sanitation, the medicine, education, wine,
public order, irrigation, roads, the fresh water system,
and public health, what have the Romans ever done for us?"
Monty Python's Life of Brian
80

^ permalink raw reply	[relevance 10%]

* Re: Visibility issue
  @ 2020-09-17 21:47  6% ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2020-09-17 21:47 UTC (permalink / raw)


On Friday, September 11, 2020 at 4:37:29 AM UTC-6, Daniel wrote:
> Hello, 
> I want to use a tagged type as a link to communicate users of a library, in the way to make one part visible to them and also to hide some content that is only needed for the implementing of the library.

Here's how that's normally achieved; I've compiled the following but haven't written a testbed/driver:

-- Daniel.ads
Package Daniel with Pure is
   -- Base Interface which all API objects implement.
   Type Abstract_Base is interface;
   
   -- All common methods.
   Function As_String(Object : Abstract_Base) return String is abstract;
   
   -- All Classwide methods.
   Function Print( Object : Abstract_Base'Class ) return String;
   
   
   -- The Callback type.
   Type Callback is access
     procedure(Item : in out Abstract_Base'Class);
   
Private
   -- The classwide "Print" returns the given object's As_String result.
   Function Print( Object : Abstract_Base'Class ) return String is
      (Object.As_String);
End Daniel;

-----------------------------------------------
-- Daniel-Implementation.ads
With
Ada.Finalization,
Ada.Strings.Equal_Case_Insensitive,
Ada.Strings.Less_Case_Insensitive,
Ada.Containers.Indefinite_Ordered_Maps;

Private Package Daniel.Implementation with Preelaborate is
   -- Fwd decl.
   Type Implementation_Base(Name_Length : Positive) is tagged private;
   
   -- Implementation_Base and its descendents have a Name, that is within the
   -- private-portion of the implementation and therefore we need an accessor.
   -- Note: Name is unique and case-insensitive.
   Function Get_Name(Object: Implementation_Base'Class) Return String;

   -- Given a name, this retrieves the object; raises constraint-error if that
   -- name is not associated with an object.
   Function Make  (Name : String) return Implementation_Base'Class;
   Function Create(Name : String) return Implementation_Base;
   Function "="(Left, Right : Implementation_Base) return Boolean;
   
Private
   -- Full decl. Note, also, that this is hidden from the API package.
   Type Implementation_Base(Name_Length : Positive) is
     new Ada.Finalization.Controlled with record
      Name : String(1..Name_Length);
   End record;
   
   -- Finalization; this will remove the registered Name from the object-map.
   overriding
   procedure Finalize   (Object : in out Implementation_Base);

   -- Instantiate the package mapping Names to Objects.
   Package Name_Map is new Ada.Containers.Indefinite_Ordered_Maps(
         Key_Type     => String,
         Element_Type => Implementation_Base'Class,
         "<" => Ada.Strings.Less_Case_Insensitive,
         "=" => "="
        );
   
   -- This is the map that associates objects and their names.
   Core_Map : Name_Map.Map;
End Daniel.Implementation;

------------------------------------------------
-- Daniel-API.ads
Private With
Daniel.Implementation;

Private Package Daniel.API with Preelaborate is
   -- The base API-visable type.
   Type API_Base(<>) is new Abstract_Base with private;
   
   -- Creation functions.
   Function Create(Name : String) return API_Base;
   Function Create(Name : String; Op : Callback) return API_Base;
   
   -- Interface functions.
   Function As_String (Object :        API_Base) return String;
   Procedure Execute  (Object : in out API_Base);
Private
   -- We derive from implementation's base, and add a discriminant for the
   -- callback and another fata-field.
   Type API_Base( CBK : Callback; Length : Positive ) is
     new Daniel.Implementation.Implementation_Base( Name_Length => Length )
     and Abstract_Base with record
      A_1 : Character := 'C';
   end record;
   
   -- We raise an exception when there is no callback given.
   Function Create(Name : String) return API_Base is
     (raise Program_Error with "Callback MUST be specified.");
   
   -- Finally, we construct an object from a call to implementation's create
   -- and fill-in the missing information using an "extension aggrigate".
   Function Create(Name : String; Op : Callback) return API_Base is
     (Implementation.Create(Name) with
      CBK => Op, Length => Name'Length, others => <>);
   
End Daniel.API;

------------------------------------------------------------------------------
-- Daniel-Implementation.adb
with
Ada.Exceptions,
Ada.Finalization;

use
Ada.Finalization;

Package Body Daniel.Implementation is
   Function "=" (Left, Right : String) return Boolean
    renames Ada.Strings.Equal_Case_Insensitive;
   
   Function Get_Name(Object: Implementation_Base'Class) Return String is
     (Object.Name);

   Function Make(Name : String) return Implementation_Base'Class is
   Begin
      Return Core_Map(Name);
   Exception
      when PE : Program_Error =>
         raise Constraint_Error with Ada.Exceptions.Exception_Message(PE);
   End Make;

   Function "="(Left, Right : Implementation_Base) return boolean is
      (Left.Name = Right.Name);
   
   Function Create(Name : String) return Implementation_Base is
   begin
      Return Result : Constant Implementation_Base :=
        (Controlled with Name_Length => Name'Length, Name => Name) do
         Core_Map.Include(New_Item => Result, Key => Name);
      end return;
   end Create;
   
   Procedure Finalize(Object : in out Implementation_Base) is
   Begin
      Core_Map.Delete( Object.Name );
   End Finalize;
   
End Daniel.Implementation;

------------------------------------------------------
-- Daniel-API.adb
Package Body Daniel.API is
   Procedure Execute  (Object : in out API_Base) is
   Begin
      Object.CBK.All(Object);
   End Execute;

   Function As_String (Object : in API_Base) return String is
   Begin
      Return '(' & Object.Get_Name & ", " & Object.A_1 & ')';
   End As_String;
End Daniel.API;

^ permalink raw reply	[relevance 6%]

* Re: Newbie question # 2
  2020-08-06 18:56  7% ` Simon Wright
@ 2020-08-06 19:41  0%   ` Ian Douglas
  0 siblings, 0 replies; 200+ results
From: Ian Douglas @ 2020-08-06 19:41 UTC (permalink / raw)


On Thursday, 6 August 2020 20:56:25 UTC+2, Simon Wright  wrote:
> 
> I'd think of a record type to contain the properties, and then a map
> from object name to properties:

Yes, the variables are actually records.

> 
>    package Object_Maps is new Ada.Containers.Indefinite_Ordered_Maps
>      (Key_Type     => String,
>       Element_Type => Properties);
> 
>    Objects : Object_Maps.Map;

Okay that's a new construct I haven't come across yet. Let me see what I can dig up on that.

Thanks, Ian

^ permalink raw reply	[relevance 0%]

* Re: Newbie question # 2
  @ 2020-08-06 18:56  7% ` Simon Wright
  2020-08-06 19:41  0%   ` Ian Douglas
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2020-08-06 18:56 UTC (permalink / raw)


Ian Douglas <ian@vionia.com> writes:

> In PHP, let's say we have a variable $fruit which contains the string
> "banana".
>
> In PHP, if I do $$fruit, then it creates a variable $banana, which I
> can then do things with.
>
> Does Ada support any such concept of taking the contents of one
> variable and using THAT as a variable?
>
> I'm reading in a file which has a name of an object followed by some
> properties so I want to use the name as a variable ...  File is
> something I created, so it's not some random stuff, and the variables
> will be existing already.

I'd think of a record type to contain the properties, and then a map
from object name to properties:

   type Properties is record
      Length : Positive;
      Width  : Positive;
   end record;

   package Object_Maps is new Ada.Containers.Indefinite_Ordered_Maps
     (Key_Type     => String,
      Element_Type => Properties);

   Objects : Object_Maps.Map;

^ permalink raw reply	[relevance 7%]

* Re: Proposal: Auto-allocation of Indefinite Objects
  @ 2020-07-27 20:31 10%     ` Jeffrey R. Carter
  0 siblings, 0 replies; 200+ results
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	[relevance 10%]

* Re: How can I get this data into the .data section of the binary?
  @ 2020-06-16 16:11  7%           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2020-06-16 16:11 UTC (permalink / raw)


On 16/06/2020 17:43, Luke A. Guest wrote:
> On 16/06/2020 16:21, Dmitry A. Kazakov wrote:
>> On 16/06/2020 16:42, Luke A. Guest wrote:
>>> On 16/06/2020 15:25, Dmitry A. Kazakov wrote:
>>>> On 16/06/2020 16:14, Niklas Holsti wrote:
>>>
>>>>> I have no idea if this will help you -- the types in our case were
>>>>> much simpler -- but you might try it with a small subset of your
>>>>> package:
>>>>>
>>>>>       Pixel_Format_Unknown     : constant Pixel_Format_Names :=
>>>>>         (True, (NUL, NUL, NUL, NUL));
>>>>>
>>>>> (assuming "use Ada.Characters.Latin_1").
>>>>
>>>> That is interesting. Was there the "others =>" part?
>>>>
>>>> I can imagine that with "others => NUL" a static zeroed section were
>>>> used with other parts written upon it during start.
>>>>
>>>> P.S. I hope more people now see why compile-time subprograms are
>>>> necessary.
>>>>
>>>
>>> I don't think Ada needs compile-time subprograms, it just needs to
>>> recognise actual static data which can be generated at compile time,
>>
>> Without calling subprograms? That is not possible in 99% of use cases.
> 
> Course it is. The compiler will translate the code into data.

Consider an array filled with Fibonacci numbers or a parser's tokens 
table or a constant instance of Ada.Containers.Vectors. It is a big 
issue for small embedded systems with instant booting time requirement.

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

^ permalink raw reply	[relevance 7%]

* Re: GNAT vs Matlab - operation on   multidimensional complex matrices
  @ 2020-06-08 17:42  4% ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2020-06-08 17:42 UTC (permalink / raw)


Cleaning out my computer, I found this working-file; it might be of interesti to you -- it shows "going all-in" with Generics:
--------------------------------------------------------------
With
Ada.Real_Time,
Ada.Containers.Indefinite_Holders,
Ada.Numerics.Long_Complex_Types,
Ada.Exceptions,
Ada.Text_IO.Complex_IO;

Procedure Demo is
    package TIO renames Ada.Text_IO;
    package CTIO is new TIO.Complex_IO(Ada.Numerics.Long_Complex_Types);

    subtype mReal   is Long_Float;
    subtype Complex is Ada.Numerics.Long_Complex_Types.Complex;


    NumIteration : constant  := 1_000;
    NumChannels  : constant  := 64;
    NumRanges    : constant  := 400;
    NumAngles    : constant  := 30;


    Type Channel is range 1..NumChannels;
    Type Angle   is range 1..NumAngles;
    Type Range_T is range 1..NumRanges;

    type tCubeReal    is array (Channel, Angle, Range_T) of mReal;
    type tCubeComplex is array (Channel, Angle, Range_T) of Complex;

    Generic
        Type T is private;
        Type IndexA is (<>);
        Type IndexB is (<>);
        Type IndexC is (<>);
        Type Cubic is Array(IndexA, IndexB, indexC) of T;
        Zero : in T;
        with Function "+"(Left, Right: T) return T is <>;
    Function Summation( Input : Cubic ) return T
      with Inline;

    Function Summation( Input : Cubic ) return T is
    Begin
        Return Result : T := Zero do
            For A in IndexA loop
                For B in IndexB loop
                    For C in IndexC loop
                        Result:= Result + Input(A, B, C);
                    End loop;
                End loop;
            End loop;
        End return;
    End Summation;

    Generic
        Type Element is private;
        Type Cubic is array (Channel, Angle, Range_T) of Element;
        Zero : In Element;
        with Function "+"(Left, Right: Element) return Element is <>;
    Procedure Timing_Harness(Mtx : in Cubic;  S: out Element; Iterations : in Positive:= 1);

    Procedure Timing_Harness(Mtx : in Cubic;  S: out Element; Iterations : in Positive:= 1) is
        Function Sum is new Summation(Element, Channel, Angle, Range_T, Cubic, Zero);
        Use Ada.Real_Time;
        Start : Time renames Clock;
    Begin
        For Count in 1..Iterations Loop
            S := Sum( Mtx );
        End loop;


        METRICS:
        Declare
            Execution_Time  : Constant Time_Span:= Clock - Start;
            Execution_Image : Constant String:= Duration'Image(To_Duration(Execution_Time));
            T : Constant mReal := mReal(To_Duration(Execution_Time))/mReal(NumIteration);
        Begin
            TIO.New_Line;
            TIO.Put_Line("Computation time:" & Execution_Image );
            TIO.Put_Line("Computation time per iteration:" & mReal'Image(T));
        End METRICS;
    End Timing_Harness;


    Function Image( Input : mReal   )  return string renames mReal'Image;
    Function Image( Input : Complex )  return string is
        ('(' & mReal'Image(Input.Re) & ", " & mReal'Image(Input.Im) & ')');
    
    Generic
        Type T is private;
        Type IndexA is (<>);
        Type IndexB is (<>);
        Type IndexC is (<>);
        Type Cubic is Array(IndexA, IndexB, indexC) of T;
        Default : in T;
    Package Test_Data is
        Type Access_Cubic is not null access all Cubic;

        Access_Data : Constant Access_Cubic := new Cubic'(others => (others => (others => Default)));
        Data        : Cubic renames Access_Data.all;
    End Test_Data;

    Generic
        Type Element    is private;
        Type Cube_Array is array (Channel, Angle, Range_T) of Element;
        Default,
        Zero      : in Element;
        Test_Name : in String;
        with Function "+"(Left, Right: Element) return Element is <>;
        with Function Image( Input : Element )  return string  is <>;
    Procedure TEST;


    Procedure TEST is

        Package Test_Set is new Test_Data(
           T       => Element,
           IndexA  => Channel,
           IndexB  => Angle,
           IndexC  => Range_T,
           Cubic   => Cube_Array,
           Default => Default
          );
        
        procedure SpeedSum is new Timing_Harness(
           Element => Element,
           Cubic   => Cube_Array,
           Zero    => Zero,
           "+"     => TEST."+"
          );
        
        Cube   : Cube_Array renames Test_Set.Data;
        Result : Element;
    Begin
        TIO.Put_Line(Test_Name & " cube");
        TIO.Put_Line(Test_Name & " type size is:" & Integer'Image(Element'Size));

        SpeedSum(
           Mtx          => Cube,
           S            => Result,
           Iterations   => NumIteration
          );

        TIO.Put_Line("Sum is:" & Image(Result));
    End TEST;

Begin
    REAL_CUBE_TEST:
    Declare
        Procedure Do_Test is new Test(
           Element    => mReal,
           Cube_Array => tCubeReal,
           Default    => 1.0,
           Zero       => 0.0,
           Test_Name  => "Real"
          );
    Begin
        Do_Test;
    End REAL_CUBE_TEST;

    TIO.Put_Line( (1..20 => '-') ); -- Separator.

    COMPLEX_CUBE_TEST:
    Declare
        Procedure Do_Test is new Test(
           "+"        => Ada.Numerics.Long_Complex_Types."+",
           Element    => Complex,
           Cube_Array => tCubeComplex,
           Default    => (Re => 1.0, Im => 1.0),
           Zero       => (Re => 0.0, Im => 0.0),
           Test_Name  => "Complex"
          );
    Begin
        Do_Test;
    End COMPLEX_CUBE_TEST;



    TIO.Put_Line( (1..20 => '-') ); -- Separator.


    Ada.Text_IO.Put_Line( "Done." );
End Demo;

^ permalink raw reply	[relevance 4%]

* Re: CONSTRAINT ERROR: erroneous memory access
  2020-06-06 23:40  7% CONSTRAINT ERROR: erroneous memory access jcupak
@ 2020-06-07 15:53  0% ` Anh Vo
  0 siblings, 0 replies; 200+ results
From: Anh Vo @ 2020-06-07 15:53 UTC (permalink / raw)


On Saturday, June 6, 2020 at 4:40:04 PM UTC-7, jcu...@gmail.com wrote:
> It has been a few years since I have written Ada; I used and taught Ada 95 back when I was working for a defense contractor. But, now that I'm retired, I wanted to get up to speed with Ada 2012, so I decided to implement a main program to see how the Shortest_Paths generic package works (taken from A.18.31, pages 574-576). But, when I read in the data and call the Shortest_Path function, it returns with CONSTRAINT ERROR: erroneous memory access. I've tried multiple times, but can't seem to figure out what I'm doing (or NOT doing) wrong. 
> 
> Here's the main program:
> 
> with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
> with Ada.Float_Text_IO;   use Ada.Float_Text_IO;
> with Ada.Text_IO;         use Ada.Text_IO;
> with Shortest_Paths;
> with Ada.Command_Line;    use Ada.Command_Line;
> with DirectedEdge;        use DirectedEdge;
> with Ada.Containers;      use Ada.Containers;
> with Ada.Exceptions;
> 
> procedure Main_Test is
> 
>    Input_File : Ada.Text_IO.File_Type;
> 
>    Vertices   : Integer; -- Number of nodes
>    Edges      : Integer; -- Number of paths
> 
>    Tail       : Integer; -- Node From
>    Head       : Integer; -- Node To
>    Weight     : Float;   -- Path Weight/Distance/Cost
> 
>    -- Instantiate Shortest Paths package with 0..Integer'Last subtype
>    package SP is new Shortest_Paths(Node => Natural);
>    
>    -- Use Edge'Read to read the Edge components into Item
>    
>    -- Display directed edge components
>    procedure Display(Edge : in SP.Edge) is
>    begin
>       Put(Edge.From, Width=>1); Put("->");
>       Put(Edge.To,   Width=>1); Put(" ");
>       Put(Float(Edge.Length), Fore => 0, Aft => 2, Exp => 0); Put(" ");
>    end Display;
> 
>    -- Display directed edge components at cursor
>    -- Replace List'Write with Display
>    procedure Display(Cursor: in SP.Adjacency_Lists.Cursor)
>    is
>       Edge : SP.Edge := SP.Adjacency_Lists.Element(Cursor);
>    begin
>       Display(Edge); -- Let other procedure do all the work
>    end Display;
> 
> begin
> 
> -- Open input file using arg 1
>    Open (File => Input_File,
>          Mode => In_File,
>          Name => Argument(1)); -- ../tinyEWD.txt
> 
>    Set_Input(Input_File);        -- Redirect input
>    New_Line;
>    Put("Processing '"); Put(Argument(1)); Put_Line("'");
> 
>    -- Read number of nodes (vertices)
>    Get(Vertices); New_Line;
>    Put("Vertices: ");Put(Vertices, width=>2);New_Line;
> 
>    -- Read number of paths (edges)
>    Get(Edges);
>    Put("Edges:    ");Put(Edges, Width=>2);New_Line(2);
> 
>    declare
>    
>       -- Constrain Vertex to zero-based subrange
>       subtype Vertex is Natural range 0..Vertices-1;
>       
>       -- Adj is DLL of Adjacency Lists for each Vertex
>       Adj    : array (Vertex) of SP.Adjacency_Lists.List;
>       
>       -- Edge is a record of Tail, Head, and Weight components
>       Edge   : SP.Edge;
>    
>    begin
>    
>       Put_Line("Creating Adjacency Lists"); New_Line;
>    
>       -- For each node, create empty list of adjacent nodes
>       Create_Empty_Adjacency_Lists: for Node in Vertex loop
>       
>          -- Initialize each adjacency list to empty
>          Adj(Node) := SP.Adjacency_Lists.Empty_List;
>       
>       end loop Create_Empty_Adjacency_Lists;
>    
>       -- Display and append new edge to adjacency list for node
>       -- Constrain Edge index to natural subrange
>       Append_New_Edge: for E in 0..Edges-1 loop
>       
>          Put("Edge:     ");Put(E, Width=>2);Put(" ");
>       
>          -- Get edge components from data file
>          Get(Tail);   -- Tail
>          Get(Head);   -- Head
>          Get(Weight); -- Distance/Weight
>       
>          -- Set edge components
>          Edge.From   := Tail;
>          Edge.To     := Head;
>          Edge.Length := SP.Distance(Weight);
>       
>          -- Display Edge
>          Display(Edge);
>          Put(" Appended to edge ");Put(Tail,1);
>          New_Line;
>       
>          -- Append new edge to From adjacency list
>          -- Indicating path to another node
>          Adj(Edge.From).Append(Edge);
>       
>       end loop Append_New_Edge;
>       New_Line;
>    
>       Close(Input_File);
>       Set_Input(Standard_Input); -- Reset input source
>    
>       Put_Line("Node Adjacency Lists");
>    
>       -- Display contents of each adjacency list
>       Display_Adjacency_Lists: for Node in Vertex loop
>       
>          Put("Adj[");Put(Node, Width=>1);Put("] ");
>       
>          declare
>             Edges  : Ada.Containers.Count_Type;
>          begin
>          
>             -- How many edges are in this node?
>             Edges := SP.Adjacency_Lists.Length(Adj(Node));
>             Put(Integer(Edges), Width => 1);
>             if (Edges > 1) then
>                Put(" Edges: ");
>             else
>                Put(" Edge:  ");
>             end if;
>          
>             -- Iterate over all nodes in this adjacency list
>             -- and Display each edge for each node
>             SP.Adjacency_Lists.Iterate(Adj(Node), Process => Display'Access);
>          
>          end;
>          New_Line;
>       
>       end loop Display_Adjacency_Lists;
>       New_Line;
>    
>       -- Create Edge-Weighted Graph of Node and Adjacency List
>       declare
>          EWG    : SP.Graphs.Vector; -- Edge Weighted Graphs
>          Path   : SP.Paths.List;    -- Shortest Path
>       begin
>       
>          Put_Line("Creating Edge-Weighted Graphs.");
>          EWG := SP.Graphs.Empty_Vector;
>          Put_Line("EWG Empty_Vector created.");
>          
>          Put("Initializing Shortest Path to empty list...");
>          Path := SP.Paths.Empty_List;
>          Put_Line("done.");
>          
>          for Vertex in 0..Vertices-1 loop
>             Put("Vertex: ");Put(Vertex, Width => 1);
>             EWG.Append(Adj(Vertex));
>             Put_Line(" appended to EWG.");
>          end loop;
>          New_Line;
>          
>          Put("EWG.Length = "); Put(Integer(EWG.Length), Width => 1);New_Line;
>       
>          Put_Line("Finding shortest path from node 0 to node 6");
>          declare
>             use Ada.Exceptions;
>          begin
>             -- Compute Shortest Path
>             Path := SP.Shortest_Path
>                (EWG, Source => 0, Target => 6);
>             exception
>                when Error: others =>
>                   New_Line;
>                   Put_Line(Exception_Name(Error));
>                   Put_Line(Exception_Message(Error));
>                   New_Line;
>                   Return;
>          end;
>       
>          Put("The Shortest Path from Node 0 to Node 6 ");
>          Put("contains "); Put(Integer(Path.Length)); Put(" entries.");
>          -- Display path
>       end;
>    
>    
>    end;
> 
> end Main_Test;
> 
> And here's the test data (taken from Algorithms, by Sedwick):
> 
> 8
> 15
> 4 5 0.35
> 5 4 0.35
> 4 7 0.37
> 5 7 0.28
> 7 5 0.28
> 5 1 0.32
> 0 4 0.38
> 0 2 0.26
> 7 3 0.39
> 1 3 0.29
> 2 7 0.34
> 6 2 0.40
> 3 6 0.52
> 6 0 0.58
> 6 4 0.93

It is hard to comment without Ada units Shortest_Path and DirectedEdge posted. In other word, your code does not compile.

Anh Vo 

^ permalink raw reply	[relevance 0%]

* CONSTRAINT ERROR: erroneous memory access
@ 2020-06-06 23:40  7% jcupak
  2020-06-07 15:53  0% ` Anh Vo
  0 siblings, 1 reply; 200+ results
From: jcupak @ 2020-06-06 23:40 UTC (permalink / raw)


It has been a few years since I have written Ada; I used and taught Ada 95 back when I was working for a defense contractor. But, now that I'm retired, I wanted to get up to speed with Ada 2012, so I decided to implement a main program to see how the Shortest_Paths generic package works (taken from A.18.31, pages 574-576). But, when I read in the data and call the Shortest_Path function, it returns with CONSTRAINT ERROR: erroneous memory access. I've tried multiple times, but can't seem to figure out what I'm doing (or NOT doing) wrong. 

Here's the main program:

with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Float_Text_IO;   use Ada.Float_Text_IO;
with Ada.Text_IO;         use Ada.Text_IO;
with Shortest_Paths;
with Ada.Command_Line;    use Ada.Command_Line;
with DirectedEdge;        use DirectedEdge;
with Ada.Containers;      use Ada.Containers;
with Ada.Exceptions;

procedure Main_Test is

   Input_File : Ada.Text_IO.File_Type;

   Vertices   : Integer; -- Number of nodes
   Edges      : Integer; -- Number of paths

   Tail       : Integer; -- Node From
   Head       : Integer; -- Node To
   Weight     : Float;   -- Path Weight/Distance/Cost

   -- Instantiate Shortest Paths package with 0..Integer'Last subtype
   package SP is new Shortest_Paths(Node => Natural);
   
   -- Use Edge'Read to read the Edge components into Item
   
   -- Display directed edge components
   procedure Display(Edge : in SP.Edge) is
   begin
      Put(Edge.From, Width=>1); Put("->");
      Put(Edge.To,   Width=>1); Put(" ");
      Put(Float(Edge.Length), Fore => 0, Aft => 2, Exp => 0); Put(" ");
   end Display;

   -- Display directed edge components at cursor
   -- Replace List'Write with Display
   procedure Display(Cursor: in SP.Adjacency_Lists.Cursor)
   is
      Edge : SP.Edge := SP.Adjacency_Lists.Element(Cursor);
   begin
      Display(Edge); -- Let other procedure do all the work
   end Display;

begin

-- Open input file using arg 1
   Open (File => Input_File,
         Mode => In_File,
         Name => Argument(1)); -- ../tinyEWD.txt

   Set_Input(Input_File);        -- Redirect input
   New_Line;
   Put("Processing '"); Put(Argument(1)); Put_Line("'");

   -- Read number of nodes (vertices)
   Get(Vertices); New_Line;
   Put("Vertices: ");Put(Vertices, width=>2);New_Line;

   -- Read number of paths (edges)
   Get(Edges);
   Put("Edges:    ");Put(Edges, Width=>2);New_Line(2);

   declare
   
      -- Constrain Vertex to zero-based subrange
      subtype Vertex is Natural range 0..Vertices-1;
      
      -- Adj is DLL of Adjacency Lists for each Vertex
      Adj    : array (Vertex) of SP.Adjacency_Lists.List;
      
      -- Edge is a record of Tail, Head, and Weight components
      Edge   : SP.Edge;
   
   begin
   
      Put_Line("Creating Adjacency Lists"); New_Line;
   
      -- For each node, create empty list of adjacent nodes
      Create_Empty_Adjacency_Lists: for Node in Vertex loop
      
         -- Initialize each adjacency list to empty
         Adj(Node) := SP.Adjacency_Lists.Empty_List;
      
      end loop Create_Empty_Adjacency_Lists;
   
      -- Display and append new edge to adjacency list for node
      -- Constrain Edge index to natural subrange
      Append_New_Edge: for E in 0..Edges-1 loop
      
         Put("Edge:     ");Put(E, Width=>2);Put(" ");
      
         -- Get edge components from data file
         Get(Tail);   -- Tail
         Get(Head);   -- Head
         Get(Weight); -- Distance/Weight
      
         -- Set edge components
         Edge.From   := Tail;
         Edge.To     := Head;
         Edge.Length := SP.Distance(Weight);
      
         -- Display Edge
         Display(Edge);
         Put(" Appended to edge ");Put(Tail,1);
         New_Line;
      
         -- Append new edge to From adjacency list
         -- Indicating path to another node
         Adj(Edge.From).Append(Edge);
      
      end loop Append_New_Edge;
      New_Line;
   
      Close(Input_File);
      Set_Input(Standard_Input); -- Reset input source
   
      Put_Line("Node Adjacency Lists");
   
      -- Display contents of each adjacency list
      Display_Adjacency_Lists: for Node in Vertex loop
      
         Put("Adj[");Put(Node, Width=>1);Put("] ");
      
         declare
            Edges  : Ada.Containers.Count_Type;
         begin
         
            -- How many edges are in this node?
            Edges := SP.Adjacency_Lists.Length(Adj(Node));
            Put(Integer(Edges), Width => 1);
            if (Edges > 1) then
               Put(" Edges: ");
            else
               Put(" Edge:  ");
            end if;
         
            -- Iterate over all nodes in this adjacency list
            -- and Display each edge for each node
            SP.Adjacency_Lists.Iterate(Adj(Node), Process => Display'Access);
         
         end;
         New_Line;
      
      end loop Display_Adjacency_Lists;
      New_Line;
   
      -- Create Edge-Weighted Graph of Node and Adjacency List
      declare
         EWG    : SP.Graphs.Vector; -- Edge Weighted Graphs
         Path   : SP.Paths.List;    -- Shortest Path
      begin
      
         Put_Line("Creating Edge-Weighted Graphs.");
         EWG := SP.Graphs.Empty_Vector;
         Put_Line("EWG Empty_Vector created.");
         
         Put("Initializing Shortest Path to empty list...");
         Path := SP.Paths.Empty_List;
         Put_Line("done.");
         
         for Vertex in 0..Vertices-1 loop
            Put("Vertex: ");Put(Vertex, Width => 1);
            EWG.Append(Adj(Vertex));
            Put_Line(" appended to EWG.");
         end loop;
         New_Line;
         
         Put("EWG.Length = "); Put(Integer(EWG.Length), Width => 1);New_Line;
      
         Put_Line("Finding shortest path from node 0 to node 6");
         declare
            use Ada.Exceptions;
         begin
            -- Compute Shortest Path
            Path := SP.Shortest_Path
               (EWG, Source => 0, Target => 6);
            exception
               when Error: others =>
                  New_Line;
                  Put_Line(Exception_Name(Error));
                  Put_Line(Exception_Message(Error));
                  New_Line;
                  Return;
         end;
      
         Put("The Shortest Path from Node 0 to Node 6 ");
         Put("contains "); Put(Integer(Path.Length)); Put(" entries.");
         -- Display path
      end;
   
   
   end;

end Main_Test;

And here's the test data (taken from Algorithms, by Sedwick):

8
15
4 5 0.35
5 4 0.35
4 7 0.37
5 7 0.28
7 5 0.28
5 1 0.32
0 4 0.38
0 2 0.26
7 3 0.39
1 3 0.29
2 7 0.34
6 2 0.40
3 6 0.52
6 0 0.58
6 4 0.93

^ permalink raw reply	[relevance 7%]

* Re: Put the access value
  2020-04-14 11:05  6% ` Jeffrey R. Carter
@ 2020-04-14 12:09  0%   ` ldries46
  0 siblings, 0 replies; 200+ results
From: ldries46 @ 2020-04-14 12:09 UTC (permalink / raw)


Op 14-4-2020 om 13:05 schreef Jeffrey R. Carter:
> On 4/14/20 9:15 AM, ldries46 wrote:
>>
>> type Buffer_Pointer is limited private;
>>
>>     type Block_Buffer is record
>>        nr       : integer;
>>        buf      : Item;
>>        previous : Buffer_Pointer := null;
>>        next     : Buffer_Pointer := null;
>>     end record;
>>
>>        El  : Buffer_Pointer := LastBuffer;
>>        El1 : Buffer_Pointer;
>>
>> I just want to see if the routing of thedifferent Buffer_Pointer's is 
>> correct so I thought Buffer_Pointer'Image(El) would show the value of 
>> The Pointer El f.i. ?x000000 for null or even the simpel decimal 
>> value 0.
>
> 1. There are no access types in this code. The declaration of type 
> Block_Buffer is invalid because null cannot be a valid visible value 
> of type Buffer_Pointer
>
> II. Assuming the full type of Buffer_Pointer is an access type, and 
> the declaration of Block_Buffer can see the full type, it appears you 
> are creating a linked list. Why not use 
> Ada.Containers.Doubly_Linked_Lists?
>
> C. Assuming you're still going to use access types, why are you 
> interested in the internal representation of access values? These will 
> probably appear to be random values that provide no information, 
> except perhaps whether the value is null
>
> iv. If you're only interested in whether an access value is null or 
> not, this can be better determined without showing the internal 
> representation:
>
> "El is null " & Boolean'Image (El = null)
>
> "El is " & (if El = null then "" else "not ") & "null"
>
Thanks to mr J.P Rosen this worked
and I have checked a Buffer random Buffer insert routinethat looked like 
it didn't work but I could see that it in fact worked correctly. I used 
the Ada Unchecked conversion.

Mr Carter the Buffer_Pointer is an access  declaration which was limited 
private. And I just had presented it for the possibility that the 
problem should be created by its limited private pro

^ permalink raw reply	[relevance 0%]

* Re: Put the access value
  @ 2020-04-14 11:05  6% ` Jeffrey R. Carter
  2020-04-14 12:09  0%   ` ldries46
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2020-04-14 11:05 UTC (permalink / raw)


On 4/14/20 9:15 AM, ldries46 wrote:
> 
> type Buffer_Pointer is limited private;
> 
>     type Block_Buffer is record
>        nr       : integer;
>        buf      : Item;
>        previous : Buffer_Pointer := null;
>        next     : Buffer_Pointer := null;
>     end record;
> 
>        El  : Buffer_Pointer := LastBuffer;
>        El1 : Buffer_Pointer;
> 
> I just want to see if the routing of thedifferent Buffer_Pointer's is correct so 
> I thought Buffer_Pointer'Image(El) would show the value of The Pointer El f.i. 
> ?x000000 for null or even the simpel decimal value 0.

1. There are no access types in this code. The declaration of type Block_Buffer 
is invalid because null cannot be a valid visible value of type Buffer_Pointer

II. Assuming the full type of Buffer_Pointer is an access type, and the 
declaration of Block_Buffer can see the full type, it appears you are creating a 
linked list. Why not use Ada.Containers.Doubly_Linked_Lists?

C. Assuming you're still going to use access types, why are you interested in 
the internal representation of access values? These will probably appear to be 
random values that provide no information, except perhaps whether the value is null

iv. If you're only interested in whether an access value is null or not, this 
can be better determined without showing the internal representation:

"El is null " & Boolean'Image (El = null)

"El is " & (if El = null then "" else "not ") & "null"

-- 
Jeff Carter
"Your mother was a hamster and your father smelt of elderberries."
Monty Python & the Holy Grail
06

^ permalink raw reply	[relevance 6%]

* Re: Generic oddness
  2020-04-12 12:32  8% Generic oddness Per Jakobsen
@ 2020-04-12 16:38  0% ` Ludovic Brenta
  0 siblings, 0 replies; 200+ results
From: Ludovic Brenta @ 2020-04-12 16:38 UTC (permalink / raw)


Per Jakobsen <pdj@knaldgas.dk> writes:
> Declaring the package List_Type from Doubly_Linked_Lists gives me
> "abstract subprogram not allowed as generic actual" unless I declare
> the "A_Intf" type in a package separate from the List_Type
> declaration, or if I instantiate a workaround (dummy) generic before
> (as in the below MWE):
>
> --- gnatchop ---------------------
> generic
>    type A is private;
> package Gen is
>    pragma Pure;
> end Gen;
> package Intf is
>    type Intf_Type is interface;
>    procedure Do_Stuff (I : in out Intf_Type) is abstract;
> end Intf;
> with Ada.Containers.Doubly_Linked_Lists;
> with Intf;
> with Gen;
>
> package Test is
>    use Intf;
>
>    type A_Intf is new Intf_Type with
>       record
>          A : Natural;
>       end record;
>
>    overriding
>    procedure Do_Stuff (I : in out A_Intf);
>
>    package Workaround is new Gen (A => A_Intf);
>    --  Commenting the above line will cause the
>    --  next line to fail !?!?
>    package List_Type is
>       new Ada.Containers.Doubly_Linked_Lists (Element_Type => A_Intf,
>                                               "="          => "=");
> end Test;
> package body Test is
>
>    overriding
>    procedure Do_Stuff (I : in out A_Intf) is
>    begin
>       null;
>    end Do_Stuff;
>
> end Test;
> --- gnatchop end ---------------------
>
> Unpack with gnatchop, then compile with gnatmake test.adb. Then
> comment the Workaround package instantiation and recompile.
>
> Using GNATMAKE Community 2019 (20190517-83).
>
> Is there a sane explanation for this behavior?

I think I have a partial explanation.  Instantiating the package Gen
freezes the type Test.A_Intf.  Similarly, if you declare A_Intf in a
package and then instantiate Doubly_Linked_Lists in another package, the
instantiation of Doubly_Linked_Lists sees a frozen type as the actual.

The part that I don't understand is why you can instantiate Gen but not
Doubly_Linked_Lists with the same actual type as parameter; I think the
instantiation of Doubly_Linked_Lists should freeze the type A_Intf just
like package Workaround does.

-- 
Ludovic Brenta.
Multi-channel structures transfer the thinkers/planners throughout the
organization. In the same time, the enabler will be well equipped to
harness an alternative.

^ permalink raw reply	[relevance 0%]

* Generic oddness
@ 2020-04-12 12:32  8% Per Jakobsen
  2020-04-12 16:38  0% ` Ludovic Brenta
  0 siblings, 1 reply; 200+ results
From: Per Jakobsen @ 2020-04-12 12:32 UTC (permalink / raw)


Declaring the package List_Type from Doubly_Linked_Lists gives me "abstract subprogram not allowed as generic actual" unless I declare the "A_Intf" type in a package separate from the List_Type declaration, or if I instantiate a workaround (dummy) generic before (as in the below MWE):

--- gnatchop ---------------------
generic
   type A is private;
package Gen is
   pragma Pure;
end Gen;
package Intf is
   type Intf_Type is interface;
   procedure Do_Stuff (I : in out Intf_Type) is abstract;
end Intf;
with Ada.Containers.Doubly_Linked_Lists;
with Intf;
with Gen;

package Test is
   use Intf;

   type A_Intf is new Intf_Type with
      record
         A : Natural;
      end record;

   overriding
   procedure Do_Stuff (I : in out A_Intf);

   package Workaround is new Gen (A => A_Intf);
   --  Commenting the above line will cause the
   --  next line to fail !?!?
   package List_Type is
      new Ada.Containers.Doubly_Linked_Lists (Element_Type => A_Intf,
                                              "="          => "=");
end Test;
package body Test is

   overriding
   procedure Do_Stuff (I : in out A_Intf) is
   begin
      null;
   end Do_Stuff;

end Test;
--- gnatchop end ---------------------

Unpack with gnatchop, then compile with gnatmake test.adb. Then comment the Workaround package instantiation and recompile.

Using GNATMAKE Community 2019 (20190517-83).

Is there a sane explanation for this behavior?

~Per

^ permalink raw reply	[relevance 8%]

* Re: Is this actually possible?
  2019-12-12  2:00  7%           ` Randy Brukardt
  2019-12-12  9:26  0%             ` Niklas Holsti
@ 2020-04-08 16:10  0%             ` Alejandro R. Mosteo
  1 sibling, 0 replies; 200+ results
From: Alejandro R. Mosteo @ 2020-04-08 16:10 UTC (permalink / raw)


I apologize for unearthing this old topic; I just came around to it.

On 12/12/19 3:00, Randy Brukardt wrote:

> This is the purpose of the Bounded_Indefinite_Holders, because this is a
> useful thing to do sometimes.
> 
>      package My_Holders is new Ada.Containers.Bounded_Indefinite_Holders
> (T'Class, 100);
> 
>      type An_Array is array (Positive range <>) of My_Holders.Holder;
> 
> Here, a Holder will hold up to 100 storage units. If some extension of
> T'Class is bigger than that, setting the holder to a value of that extension
> raises Program_Error. (As with most checks, this one can be suppressed, and
> if it would fail and is suppressed, the program is erroneous - presumably
> some other object memory would be overwritten. So don't do that. ;-)
> 
> This is probably one of the best (and simplest) ideas of Ada 202x. Thanks to
> Niklas Holsti for the original idea (although I think the actual resulting
> package isn't much like Niklas' original idea).

I tried to use the GNAT CE 2019 Bounded_Holders once and got bitten by 
them being implemented with casts/address wizardry. This meant that 
storing controlled types and copying them while in bounded disguise 
broke finalization internals. (I don't remember the specifics, sorry).

Is this an implementation allowance? I see note 13/5 at 
http://www.ada-auth.org/standards/2xrm/html/RM-A-18-32.html#I8180 that 
implies that Finalization should work.

But then I also realize that the ARM package name is 
Bounded_Indefinite_Holders and not Bounded_Holders, so maybe the version 
I used is an early implementation.

(This is what I have: 
https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/libgnat/a-coboho.ads)

^ permalink raw reply	[relevance 0%]

* Re: multidimensional sort
  2020-03-17 17:24  9%   ` Simon Wright
@ 2020-03-17 20:16  0%     ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2020-03-17 20:16 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> Unless OP has some unstated requirements, I'd think that just
> Ada.Containers.Generic_Array_Sort would do the trick:

I should have said, ARM A.18.26(2),
http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-A-18-26.html#p2

^ permalink raw reply	[relevance 0%]

* Re: multidimensional sort
  2020-03-17 12:56  7% ` Petter Fryklund
@ 2020-03-17 17:24  9%   ` Simon Wright
  2020-03-17 20:16  0%     ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2020-03-17 17:24 UTC (permalink / raw)


Petter Fryklund <petter.fryklund@atero.se> writes:

> Den tisdag 17 mars 2020 kl. 13:31:43 UTC+1 skrev Gilbert Gosseyn:
>> I want to sort an n-dim array by ascending dimensions and ascending
>> elements as keys, in Ada. For example:
>> consider an array with n = 5 like:
>> 
>> ((5, 8, 21, 37, 46), (5, 7, 12, 19, 26),
>>  (10, 12, 19, 33, 44), (7, 8, 34, 36, 38), (5, 11, 12, 27, 32), (10, 
>>   16, 30, 41, 45), (10, 13, 19, 40, 45), (10, 11, 18, 32, 41), (11, 
>>   28, 34, 37, 38))
>> 
>> which shall become
>> 
>> ((5, 7, 12, 19, 26), (5, 8, 21, 37, 46), (5, 11, 12, 27, 32), (7, 8, 
>>   34, 36, 38), (10, 11, 18, 32, 41), (10, 12, 19, 33, 44), (10, 13, 
>>   19, 40, 45), (10, 16, 30, 41, 45), (11, 28, 34, 37, 38))
>> 
>> How to store, how to sort, and how to deallocate the original?
>> 
>> Thank you for your advice.
>
> This looks very much like homework. Have a look at
> Ada.Containers.Indefinate_Vectors and the generic procedure
> Generic_Sorting.

Unless OP has some unstated requirements, I'd think that just
Ada.Containers.Generic_Array_Sort would do the trick:

   type Arr is array (1 .. 5) of Positive;
   type Arrays is array (Positive range <>) of Arr;
   function "<" (L, R : Arr) return Boolean;

   procedure Sort is new Ada.Containers.Generic_Array_Sort
     (Index_Type   => Positive,
      Element_Type => Arr,
      Array_Type   => Arrays);

The trick is to get "<" right!

OP, what's wrong with

   Data : Arrays :=
     ((5, 8, 21, 37, 46),
      (5, 7, 12, 19, 26),
      ...
      (11, 28, 34, 37, 38));

which doesn't need deallocation at all.

^ permalink raw reply	[relevance 9%]

* Re: multidimensional sort
  @ 2020-03-17 12:56  7% ` Petter Fryklund
  2020-03-17 17:24  9%   ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: Petter Fryklund @ 2020-03-17 12:56 UTC (permalink / raw)


Den tisdag 17 mars 2020 kl. 13:31:43 UTC+1 skrev Gilbert Gosseyn:
> I want to sort an n-dim array by ascending dimensions and ascending elements as keys, in Ada. For example:
> consider an array with n = 5 like:
> 
> ((5, 8, 21, 37, 46), (5, 7, 12, 19, 26),
>  (10, 12, 19, 33, 44), (7, 8, 34, 36, 38), (5, 11, 12, 27, 32), (10, 
>   16, 30, 41, 45), (10, 13, 19, 40, 45), (10, 11, 18, 32, 41), (11, 
>   28, 34, 37, 38))
> 
> which shall become
> 
> ((5, 7, 12, 19, 26), (5, 8, 21, 37, 46), (5, 11, 12, 27, 32), (7, 8, 
>   34, 36, 38), (10, 11, 18, 32, 41), (10, 12, 19, 33, 44), (10, 13, 
>   19, 40, 45), (10, 16, 30, 41, 45), (11, 28, 34, 37, 38))
> 
> How to store, how to sort, and how to deallocate the original?
> 
> Thank you for your advice.

This looks very much like homework. Have a look at Ada.Containers.Indefinate_Vectors and the generic procedure Generic_Sorting.


Regards,
Petter 

^ permalink raw reply	[relevance 7%]

* Containers, dangling references
@ 2020-03-09 16:43  8% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2020-03-09 16:43 UTC (permalink / raw)


I've been working on checking the upcoming FSF GCC 10 against existing
projects.

One case is a set of containers which include reference types (which,
under the hood, support for example the "for all X of Y" iteration
style).

The original version of the code looked like

   type Reference_Type
     (Element : not null access Element_Type)
      is record
         Dummy : Integer := raise Program_Error with "uninitialized reference";
      end record;

(this is the full declaration; Dummy is there so that default
initialization will raise PE, as required, e.g. ARM A.18.2(147.4)).

   function Reference
     (C :aliased in out Container; Position : in Cursor)
     return Reference_Type;

with implementation

   function Reference (C : aliased in out Container; Position : in Cursor)
                      return Reference_Type
   is
      pragma Unreferenced (C);
   begin
      return (Element => Position.The_Node.all.The_Element'Access, Dummy => 1);
   end Reference;

which was fine with compilers up to FSF GCC 9, GNAT CE 2019. With GCC
10, we get

   references.adb:8:26: access discriminant in return aggregate would be
   a dangling reference

I was a bit puzzled by the Position.The_Node.all.The_Element'Access -
why the .all? It turns out that if you remove it, the compilers that
were happy are no longer. Perhaps this was some circuitry in GNAT to
suppress this error?

How do the Ada.Containers manage this? It turns out that GNAT's
version is more like

      return R : constant Reference_Type :=
        (Element => Position.The_Node.The_Element'Access, Dummy => 1)
      do
         null;
      end return;

and this is fine in GCC 10 (but if you put in the .all the error
message returns).

I found where the error message is raised[1], but it's hard to tell
what the compiler is actually checking for.

[1] https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/sem_ch6.adb#L858

^ permalink raw reply	[relevance 8%]

* Re: Different aliasing rules for containers?
  2020-02-20 13:36  0% ` joakimds
@ 2020-02-20 13:47  0%   ` Martin B. B.
  0 siblings, 0 replies; 200+ results
From: Martin B. B. @ 2020-02-20 13:47 UTC (permalink / raw)


On Thursday, 20 February 2020 14:36:38 UTC+1, joak...@kth.se  wrote:
> Den torsdag 20 februari 2020 kl. 13:24:37 UTC+1 skrev Martin B. B.:
> > The following code:
> > 
> > with Ada.Containers.Vectors;
> > with Ada.Text_IO;
> > 
> > procedure Test is
> > 
> >    package IO renames Ada.Text_IO;
> > 
> >    type Obj is record
> >       Id : Integer;
> >    end record;
> > 
> >    package Obj_Vectors is new Ada.Containers.Vectors
> >      (Index_Type   => Positive,
> >       Element_Type => Obj);
> >    
> >    use type Obj_Vectors.Vector;
> >       
> >    Objects : Obj_Vectors.Vector := Obj'(Id => 0) & Obj'(Id => 1) & Obj'(Id => 2);
> > 
> > begin
> >    for O of Objects loop
> >       O.Id := 999;
> >    end loop;
> >    
> >    for O of Objects loop
> >       IO.Put_Line (Integer'Image (O.Id));
> >    end loop;
> > end Test;
> > 
> > Using GNAT Community 2019 (20190517-83) produces the following output:
> >  999
> >  999
> >  999
> > 
> > When looking at the Ada.Containers.Vectors package specification, I see the following:
> >    type Vector is tagged private
> >    with
> >       Constant_Indexing => Constant_Reference,
> >       Variable_Indexing => Reference,
> >       Default_Iterator  => Iterate,
> >       Iterator_Element  => Element_Type;
> > 
> > However, both the `Rerefence` and `Constant_Reference` functions takes aliased parameters:
> >    function Reference
> >      (Container : aliased in out Vector;
> >       Position  : Cursor) return Reference_Type;
> > 
> > My question is then: How is the code above possible then, when my `Objects` vector is not aliased? Shouldn't the compiler complain that I haven't declared `Objects` as being aliased?
> > 
> > Even creating my own procedure that takes a `V : aliased Obj_Vectors.Vector` still produces no aliasing errors when passing it a non-aliased vector.
> > 
> > This code:
> > with Ada.Text_IO;
> > 
> > procedure Test is
> > 
> >    package IO renames Ada.Text_IO;
> >    
> >    procedure Takes_Aliased_Integer (X : aliased Integer);
> > 
> >    procedure Takes_Aliased_Integer (X : aliased Integer) is
> >    begin
> >       null;
> >    end Takes_Aliased_Integer;
> > 
> >    My_Int : Integer := 123;
> > 
> > begin
> >    Takes_Aliased_Integer (My_Int);
> > end Test;
> > 
> > However, correctly(?) generates the following compiler error: "actual for aliased formal "X" must be aliased object".
> > 
> > So, what exactly is going on here? Am I missing something?
> 
> Hi Martin,
> 
> Could it be because Obj_Vectors.Vector is a tagged type and is therefore always passed by reference in subprogram calls and that implies it is aliased?
> 
> Best regards,
> Joakim

Ah, it seems you are correct! I was not aware of this difference between tagged and non-tagged types.

It seems to be what is mentioned here in the reference manual: "Finally, a formal parameter or generic formal object of a tagged type is defined to be aliased" (http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-3-10.html#p9)

Thank you for the help :)

^ permalink raw reply	[relevance 0%]

* Re: Different aliasing rules for containers?
  2020-02-20 12:24  9% Different aliasing rules for containers? Martin B. B.
@ 2020-02-20 13:36  0% ` joakimds
  2020-02-20 13:47  0%   ` Martin B. B.
  0 siblings, 1 reply; 200+ results
From: joakimds @ 2020-02-20 13:36 UTC (permalink / raw)


Den torsdag 20 februari 2020 kl. 13:24:37 UTC+1 skrev Martin B. B.:
> The following code:
> 
> with Ada.Containers.Vectors;
> with Ada.Text_IO;
> 
> procedure Test is
> 
>    package IO renames Ada.Text_IO;
> 
>    type Obj is record
>       Id : Integer;
>    end record;
> 
>    package Obj_Vectors is new Ada.Containers.Vectors
>      (Index_Type   => Positive,
>       Element_Type => Obj);
>    
>    use type Obj_Vectors.Vector;
>       
>    Objects : Obj_Vectors.Vector := Obj'(Id => 0) & Obj'(Id => 1) & Obj'(Id => 2);
> 
> begin
>    for O of Objects loop
>       O.Id := 999;
>    end loop;
>    
>    for O of Objects loop
>       IO.Put_Line (Integer'Image (O.Id));
>    end loop;
> end Test;
> 
> Using GNAT Community 2019 (20190517-83) produces the following output:
>  999
>  999
>  999
> 
> When looking at the Ada.Containers.Vectors package specification, I see the following:
>    type Vector is tagged private
>    with
>       Constant_Indexing => Constant_Reference,
>       Variable_Indexing => Reference,
>       Default_Iterator  => Iterate,
>       Iterator_Element  => Element_Type;
> 
> However, both the `Rerefence` and `Constant_Reference` functions takes aliased parameters:
>    function Reference
>      (Container : aliased in out Vector;
>       Position  : Cursor) return Reference_Type;
> 
> My question is then: How is the code above possible then, when my `Objects` vector is not aliased? Shouldn't the compiler complain that I haven't declared `Objects` as being aliased?
> 
> Even creating my own procedure that takes a `V : aliased Obj_Vectors.Vector` still produces no aliasing errors when passing it a non-aliased vector.
> 
> This code:
> with Ada.Text_IO;
> 
> procedure Test is
> 
>    package IO renames Ada.Text_IO;
>    
>    procedure Takes_Aliased_Integer (X : aliased Integer);
> 
>    procedure Takes_Aliased_Integer (X : aliased Integer) is
>    begin
>       null;
>    end Takes_Aliased_Integer;
> 
>    My_Int : Integer := 123;
> 
> begin
>    Takes_Aliased_Integer (My_Int);
> end Test;
> 
> However, correctly(?) generates the following compiler error: "actual for aliased formal "X" must be aliased object".
> 
> So, what exactly is going on here? Am I missing something?

Hi Martin,

Could it be because Obj_Vectors.Vector is a tagged type and is therefore always passed by reference in subprogram calls and that implies it is aliased?

Best regards,
Joakim

^ permalink raw reply	[relevance 0%]

* Different aliasing rules for containers?
@ 2020-02-20 12:24  9% Martin B. B.
  2020-02-20 13:36  0% ` joakimds
  0 siblings, 1 reply; 200+ results
From: Martin B. B. @ 2020-02-20 12:24 UTC (permalink / raw)


The following code:

with Ada.Containers.Vectors;
with Ada.Text_IO;

procedure Test is

   package IO renames Ada.Text_IO;

   type Obj is record
      Id : Integer;
   end record;

   package Obj_Vectors is new Ada.Containers.Vectors
     (Index_Type   => Positive,
      Element_Type => Obj);
   
   use type Obj_Vectors.Vector;
      
   Objects : Obj_Vectors.Vector := Obj'(Id => 0) & Obj'(Id => 1) & Obj'(Id => 2);

begin
   for O of Objects loop
      O.Id := 999;
   end loop;
   
   for O of Objects loop
      IO.Put_Line (Integer'Image (O.Id));
   end loop;
end Test;

Using GNAT Community 2019 (20190517-83) produces the following output:
 999
 999
 999

When looking at the Ada.Containers.Vectors package specification, I see the following:
   type Vector is tagged private
   with
      Constant_Indexing => Constant_Reference,
      Variable_Indexing => Reference,
      Default_Iterator  => Iterate,
      Iterator_Element  => Element_Type;

However, both the `Rerefence` and `Constant_Reference` functions takes aliased parameters:
   function Reference
     (Container : aliased in out Vector;
      Position  : Cursor) return Reference_Type;

My question is then: How is the code above possible then, when my `Objects` vector is not aliased? Shouldn't the compiler complain that I haven't declared `Objects` as being aliased?

Even creating my own procedure that takes a `V : aliased Obj_Vectors.Vector` still produces no aliasing errors when passing it a non-aliased vector.

This code:
with Ada.Text_IO;

procedure Test is

   package IO renames Ada.Text_IO;
   
   procedure Takes_Aliased_Integer (X : aliased Integer);

   procedure Takes_Aliased_Integer (X : aliased Integer) is
   begin
      null;
   end Takes_Aliased_Integer;

   My_Int : Integer := 123;

begin
   Takes_Aliased_Integer (My_Int);
end Test;

However, correctly(?) generates the following compiler error: "actual for aliased formal "X" must be aliased object".

So, what exactly is going on here? Am I missing something?

^ permalink raw reply	[relevance 9%]

* use type does not seem to work for types in generic package instantiations
@ 2020-02-18  1:37  8% yoehoduv
  0 siblings, 0 replies; 200+ results
From: yoehoduv @ 2020-02-18  1:37 UTC (permalink / raw)


It looks like use type has no effect when the type is from a package
declared in the same region as the use type statement.

I can make the primitive subprograms of a type directly visible with
`use all type` like this:

     package Type_Package is
        type T is null record;
        procedure Action(X: T) is null;
     end Type_Package;

     with Type_Package;
     procedure Use_Type is
        use all type Type_Package.T;
        X: Type_Package.T;
     begin
        Action(X);
     end Use_Type;

However, it does not seem to work when I move `Type_Package` inside
`Use_Type`.

     procedure Use_Type is
        package Type_Package is
           type T is null record;
           procedure Action(X: T) is null;
        end Type_Package;
        use all type Type_Package.T;
        X: Type_Package.T;
     begin
        Action(X);
     end Use_Type;

I get

     gcc -c use_type.adb
     use_type.adb:9:04: "Action" is not visible
     use_type.adb:9:04: non-visible declaration at line 4
     gnatmake: "use_type.adb" compilation error

The same thing occurs when I instantiate a generic package.  For
example, when I want to use the data types in `Ada.Containers`.

     package Element_Set is
        new Ada.Containers.Hashed_Sets(Element_Type, Hash, "=");
     use all type Element_Set.Set;

The `use type` clause here seems to have no effect.

Does anyone know why?

I originally posted this at
<https://stackoverflow.com/questions/60246613/how-to-use-a-type-from-a-child-package-generic-package-instantiation>

^ permalink raw reply	[relevance 8%]

* Re: Simple Components: adding an existing object to a graph
  2020-01-26 14:48  7% ` Jeffrey R. Carter
  2020-01-26 15:39  0%   ` Mart van de Wege
@ 2020-01-26 15:49  0%   ` Mart van de Wege
  1 sibling, 0 replies; 200+ results
From: Mart van de Wege @ 2020-01-26 15:49 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:

> On 1/26/20 11:23 AM, Mart van de Wege wrote:
>> This one's for Dimitry, probably: I want to create a genealogy of
>> persons using his generic directed weighted graph package.
>
> Since a genealogy is a tree, wouldn't it make more sense to use
> Ada.Containers.Multiway_Trees?

Side note: A genealogy is only a tree if you only consider matrilineal
or patrilineal descent. A full genealogy is mathematically a Directed
Acyclic Graph.

Mart

-- 
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.


^ permalink raw reply	[relevance 0%]

* Re: Simple Components: adding an existing object to a graph
  2020-01-26 14:48  7% ` Jeffrey R. Carter
@ 2020-01-26 15:39  0%   ` Mart van de Wege
  2020-01-26 15:49  0%   ` Mart van de Wege
  1 sibling, 0 replies; 200+ results
From: Mart van de Wege @ 2020-01-26 15:39 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:

> On 1/26/20 11:23 AM, Mart van de Wege wrote:
>> This one's for Dimitry, probably: I want to create a genealogy of
>> persons using his generic directed weighted graph package.
>
> Since a genealogy is a tree, wouldn't it make more sense to use
> Ada.Containers.Multiway_Trees?

I looked at that first, but how would you model the fact that a child
has 2 parents in a tree? As far as I can see Multiway_Trees is still
stuck in the model that every child node can have only one parent.

My idea was to link nodes, which can have multiple connections, using
the family relationship as a weight (using an enumeration type for the
relationships).

Regards,

Mart

-- 
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.


^ permalink raw reply	[relevance 0%]

* Re: Simple Components: adding an existing object to a graph
  @ 2020-01-26 14:48  7% ` Jeffrey R. Carter
  2020-01-26 15:39  0%   ` Mart van de Wege
  2020-01-26 15:49  0%   ` Mart van de Wege
  0 siblings, 2 replies; 200+ results
From: Jeffrey R. Carter @ 2020-01-26 14:48 UTC (permalink / raw)


On 1/26/20 11:23 AM, Mart van de Wege wrote:
> This one's for Dimitry, probably: I want to create a genealogy of
> persons using his generic directed weighted graph package.

Since a genealogy is a tree, wouldn't it make more sense to use 
Ada.Containers.Multiway_Trees?

-- 
Jeff Carter
"Perfidious English mouse-dropping hoarders."
Monty Python & the Holy Grail
10

^ permalink raw reply	[relevance 7%]

* Re: Tally
  @ 2020-01-15  3:40  9%   ` Brad Moore
  0 siblings, 0 replies; 200+ results
From: Brad Moore @ 2020-01-15  3:40 UTC (permalink / raw)


On Tuesday, January 14, 2020 at 2:08:16 PM UTC-7, Jeffrey R. Carter wrote:

> A lot depends on what restraints the problem domain puts on the input values. If 
> you can define something like
> 
> type Input_Number is range 1 .. 10;
> 
> then you can do something straightforward like
> 
> type Count_Map is array (Input_Number) of Natural;
> 
> Count  : Count_Map := (others => 0);
> Number : Input_Number;
> ...
> loop
>     exit when No_More_Numbers;
> 
>     Number := Next_Number;
>     Count (Number) := Count (Number) + 1;
> end loop;
> 
> If you can't limit the input numbers to a sufficiently small range that an 
> object like Count can be declared, then you'll need to use a map, as Holsti 
> suggested, which is only a little more complicated.
> 

Just to clarify, I'd say using a Map is more complex (quite a bit actually) in terms of what is happening semantically when the program executes, but I think it is worth noting that there is not necessarily much difference in complexity in terms of what the user has to write. As Jeff notes, using a map does has the advantage of flexibility, for example in handling sparsely populated data where there is a large range of input values.

e.g.

with Ada.Containers.Ordered_Maps; use Ada;

procedure Main
is
   package Count_Maps is new
     Containers.Ordered_Maps (Key_Type     => Natural,
                              Element_Type => Natural);
   
   type Input_Data is array (Natural range <>) of Natural;
   
   Input : Input_Data := (2, 3, 8, 2, 2, 2, 7, 2, 3, 4, 8);
   
   Counts : Count_Maps.Map;
      
begin
   for Number of Input loop
      Counts (Number) := Counts (Number) + 1;
   end loop;
end Main;

Brad

^ permalink raw reply	[relevance 9%]

* Re: Is this actually possible?
  2019-12-12  2:00  7%           ` Randy Brukardt
@ 2019-12-12  9:26  0%             ` Niklas Holsti
  2020-04-08 16:10  0%             ` Alejandro R. Mosteo
  1 sibling, 0 replies; 200+ results
From: Niklas Holsti @ 2019-12-12  9:26 UTC (permalink / raw)


On 2019-12-12 4:00, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:qsrncj$u95$1@gioia.aioe.org...
>> On 2019-12-11 22:12, Lucretia wrote:
> ...
>> Why? You must know all variants in order to compute the array element
>> size. In Ada you cannot have it either:
>>
>>     type Not_an_Array is array (Positive range <>) of T'Class;
>>
>> This is illegal.
> 
> This is the purpose of the Bounded_Indefinite_Holders, because this is a
> useful thing to do sometimes.
> 
>      package My_Holders is new Ada.Containers.Bounded_Indefinite_Holders
> (T'Class, 100);
> 
>      type An_Array is array (Positive range <>) of My_Holders.Holder;
> 
> Here, a Holder will hold up to 100 storage units. If some extension of
> T'Class is bigger than that, setting the holder to a value of that extension
> raises Program_Error. (As with most checks, this one can be suppressed, and
> if it would fail and is suppressed, the program is erroneous - presumably
> some other object memory would be overwritten. So don't do that. ;-)
> 
> This is probably one of the best (and simplest) ideas of Ada 202x. Thanks to
> Niklas Holsti for the original idea (although I think the actual resulting
> package isn't much like Niklas' original idea).

Thanks for the credit, Randy.

I wanted a way to statically allocate a "max size" for class-wide 
objects, just as many compilers currently use an "allocate max size" for 
variant records with a default discriminant. My suggestion would also 
have needed the ability to change the tag of such a class-wide object, 
just as the discriminant of a variant-record object can be changed by 
assigning to the whole object.

The wise heads of the ARG introduced the Bounded_Indefinite_Holder, 
giving just this effect: a bounded size, allowing static storage 
allocation, but also letting me change the tag by replacing the object 
being held with another object.

My only worry about the present solution is if there is a lot of memory 
overhead in the Bounded_Indefinite_Holder. I don't see why there should 
be, but I guess I'll have to wait for an implementation to find out.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[relevance 0%]

* Re: Is this actually possible?
  @ 2019-12-12  2:00  7%           ` Randy Brukardt
  2019-12-12  9:26  0%             ` Niklas Holsti
  2020-04-08 16:10  0%             ` Alejandro R. Mosteo
  0 siblings, 2 replies; 200+ results
From: Randy Brukardt @ 2019-12-12  2:00 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:qsrncj$u95$1@gioia.aioe.org...
> On 2019-12-11 22:12, Lucretia wrote:
...
> Why? You must know all variants in order to compute the array element 
> size. In Ada you cannot have it either:
>
>    type Not_an_Array is array (Positive range <>) of T'Class;
>
> This is illegal.

This is the purpose of the Bounded_Indefinite_Holders, because this is a 
useful thing to do sometimes.

    package My_Holders is new Ada.Containers.Bounded_Indefinite_Holders 
(T'Class, 100);

    type An_Array is array (Positive range <>) of My_Holders.Holder;

Here, a Holder will hold up to 100 storage units. If some extension of 
T'Class is bigger than that, setting the holder to a value of that extension 
raises Program_Error. (As with most checks, this one can be suppressed, and 
if it would fail and is suppressed, the program is erroneous - presumably 
some other object memory would be overwritten. So don't do that. ;-)

This is probably one of the best (and simplest) ideas of Ada 202x. Thanks to 
Niklas Holsti for the original idea (although I think the actual resulting 
package isn't much like Niklas' original idea).

                         Randy.





^ permalink raw reply	[relevance 7%]

* Re: Is this actually possible?
  2019-12-11 16:43  7% Is this actually possible? Lucretia
  @ 2019-12-11 19:59  0% ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Randy Brukardt @ 2019-12-11 19:59 UTC (permalink / raw)


"Lucretia" <laguest9000@googlemail.com> wrote in message 
news:36d45c82-2a6b-4c60-baeb-1a4aef5189c7@googlegroups.com...
...
> So, I tried a few things, including Holders, which I never knew existed, 
> but this is where I am currently:
>
> with Interfaces.C;
> -- with Ada.Containers.Bounded_Holders;

There no Bounded_Holders in Ada (any version). Perhaps your compiler has 
invented it (they're allowed to add containers).

Ada 202x has Bounded_Indefinite_Holders.

                  Randy.


^ permalink raw reply	[relevance 0%]

* Is this actually possible?
@ 2019-12-11 16:43  7% Lucretia
    2019-12-11 19:59  0% ` Randy Brukardt
  0 siblings, 2 replies; 200+ results
From: Lucretia @ 2019-12-11 16:43 UTC (permalink / raw)


Hi,

I was thinking about extensible records recently (not tagged types), and thought to try to export a tagged type to C, not C++. It compiles, but the results aren't quite right, so wondering if it's possible or not.

The idea is to export an array of tagged types as a C array to either a function or a variable / struct element. i.e.

struct Blah {
    My_Array *Array;
};

or in this case (Array below):

#include <stdio.h>

typedef struct {
    int One;
    float Two;
} Packet;

void Dump (int First, int Last, Packet *Array) {
    printf ("Dump (%d .. %d)\n", First, Last);
    printf ("Array => %p\n", Array);
    
    for (int I = First; I < Last + 1; I++) {
        printf ("\tOne => %d\n", Array[I].One);
        printf ("\tTwo => %f\n", Array[I].Two);
    }
}

So, I tried a few things, including Holders, which I never knew existed, but this is where I am currently:

with Interfaces.C;
-- with Ada.Containers.Bounded_Holders;
with System;

package Datums is
   package C renames Interfaces.C;

   --  Force a size, we kind of want a variant like array of records, but with unknown element types, but always of
   --  the same number and size of elements.
   type Root_Packet is abstract tagged null record with
     Size => C.int'Size + C.C_float'Size;

   -- package Root_Holders is new Ada.Containers.Bounded_Holders (Element_Type => Root_Packet'Class);
   type Storage_Element is mod 2 ** System.Storage_Unit with
     Convention => C;

   type Storage_Array is array (Positive range <>) of Storage_Element with
     Convention => C;

   type Root_Holder is
      record
         Data : Storage_Array (1 .. Root_Packet'Max_Size_In_Storage_Elements);
      end record with
        Convention => C;

   type Packet_Array is array (C.size_t range <>) of aliased Root_Holder with --  Root_Holders.Holder with
     Convention => C;

   type Packet_Array_Ptr is access all Packet_Array with
     Convention => C;

   type Packet_1 is new Root_Packet with
      record
         One : C.int;
         Two : C.C_float;
      end record with
        Convention => C;

   type Packet_2 is new Root_Packet with
      record
         Banana : C.int;
         Mango  : C.C_float;
      end record with
        Convention => C;
end Datums;

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Unchecked_Conversion;
with System.Address_Image;
with Datums; use Datums;

procedure Testing is
   -- use Root_Holders;

   function To_Holder is new Ada.Unchecked_Conversion (Source => Packet_1, Target => Root_Holder);
   function To_Holder is new Ada.Unchecked_Conversion (Source => Packet_2, Target => Root_Holder);

   A : aliased Packet_Array := (1 => To_Holder (Packet_1'(One => 10, Two => 3.14)),
                                2 => To_Holder (Packet_2'(Banana => 50, Mango => 4.5)));

   procedure Dump (First, Last : in C.int; Data : in Packet_Array_Ptr) with
     Convention    => C,
     Import        => True,
     External_Name => "Dump";
begin
   Put_Line ("A'Address => " & System.Address_Image (A'Address));

   Dump (C.int (A'First), C.int (A'Last), A'Unchecked_Access);
end Testing;

project T is
    for Source_Dirs use (".");
    for Languages use ("C", "Ada");
    for Main use ("testing.adb");

    package Compiler is
        for Default_Switches ("Ada") use ("-g");
        for Default_Switches ("C") use ("-g");
    end Compiler;
end T;

^ permalink raw reply	[relevance 7%]

* Re: Type naming conventions: Any_Foo
  2019-12-07 10:28  0%                     ` Jeffrey R. Carter
@ 2019-12-07 12:36  0%                       ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2019-12-07 12:36 UTC (permalink / raw)


On 2019-12-07 12:28, Jeffrey R. Carter wrote:
> On 12/7/19 1:57 AM, Randy Brukardt wrote:
>>
>> Agreed. Ada.Containers all have a function Element that retrieves a (copy
>> of) a single element object from the container. If the type was named
>> element, what would this function be called? Similarly, some of the
>> parameters are called Element (thus, Element : Element_Type in many
>> parameter lists); those also would need alternate names.
> 
> At a conference long ago (probably in the Ada-83 days), a presenter 
> claimed that well designed Ada has 90% of its operations named Put or 
> Get.

Horror. The result of blind OO convention :-)

> Get is an appropriate name for such an operation.

I follow the convention that procedure names are verbs ("Get") or verb 
phrases ("Remove_Last_Item") that describe the action or its effects, 
while function names are nouns ("Element") or noun phrases 
("Largest_Element") that describe the value returned by the function.

Therefore, IMO, "Get" is not a proper name for a function (unless the 
program models animal breeding, and the Get function returns all the 
offspring of a particular animal or pair of animals).

> More specifically, good names may depend on the data structure. When the 
> normal Get operation modifies the structure, as for queues and stacks, 
> Peek is a good name.

For stacks, Push and Pop.

For queues, Enqueue and Dequeue.

Functions should usually not modify their parameter structures; I use 
procedures for that.

> Value is a good name for most other cases.

Sometimes, but often it is too general. And it it ambiguous, because it 
can also mean "worth" or "usefulness".

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


^ permalink raw reply	[relevance 0%]

* Re: Type naming conventions: Any_Foo
  2019-12-07  0:57  7%                   ` Randy Brukardt
@ 2019-12-07 10:28  0%                     ` Jeffrey R. Carter
  2019-12-07 12:36  0%                       ` Niklas Holsti
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2019-12-07 10:28 UTC (permalink / raw)


On 12/7/19 1:57 AM, Randy Brukardt wrote:
> 
> Agreed. Ada.Containers all have a function Element that retrieves a (copy
> of) a single element object from the container. If the type was named
> element, what would this function be called? Similarly, some of the
> parameters are called Element (thus, Element : Element_Type in many
> parameter lists); those also would need alternate names.

At a conference long ago (probably in the Ada-83 days), a presenter claimed that 
well designed Ada has 90% of its operations named Put or Get. Get is an 
appropriate name for such an operation.

More specifically, good names may depend on the data structure. When the normal 
Get operation modifies the structure, as for queues and stacks, Peek is a good 
name. Value is a good name for most other cases.

Parameters of the type should be named Item.

-- 
Jeff Carter
"C++ is like jamming a helicopter inside a Miata
and expecting some sort of improvement."
Drew Olbrich
51

^ permalink raw reply	[relevance 0%]

* Re: Type naming conventions: Any_Foo
  2019-12-06 20:35  0%                 ` Dmitry A. Kazakov
@ 2019-12-07  0:57  7%                   ` Randy Brukardt
  2019-12-07 10:28  0%                     ` Jeffrey R. Carter
  0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2019-12-07  0:57 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:qsee2v$par$1@gioia.aioe.org...
> On 2019-12-06 21:18, Jeffrey R. Carter wrote:
>> On 12/5/19 10:51 PM, Dmitry A. Kazakov wrote:
>>>
>>> Ada standard library uses _Type, e.g.
>>>
>>> generic
>>> type Element_Type (<>) is private;
>>> with function "=" (Left, Right : Element_Type) return Boolean is <>;
>>> package Ada.Containers.Indefinite_Holders
>>
>> Yes, and the ARM also includes such abominations as anonymous access 
>> types. Just because it's in the ARM doesn't mean it's the best way to do 
>> something. Element is be a better name for that formal type.
>
> No, it would be misleading. Element must be reserved for instances of the 
> type. They are actual elements. The type of an element is not an element, 
> these are two totally different things.

Agreed. Ada.Containers all have a function Element that retrieves a (copy 
of) a single element object from the container. If the type was named 
element, what would this function be called? Similarly, some of the 
parameters are called Element (thus, Element : Element_Type in many 
parameter lists); those also would need alternate names.

There were a number of ARG members that disliked the "_Type" notation, so we 
looked at alternatives. And we didn't find anything that worked as well. 
Sometimes, package design is about the "least bad" alternative.

                                     Randy.




>>> There are lots of cases in Ada, you certainly should know that. As a 
>>> practical example GtkAda declares all widget types twice:
>>>
>>> type Gtk_Button_Record is ...
>>> type Gtk_Button is access all Gtk_Button_Record'Class;
>>
>> No well designed library has public access types. You aren't required to 
>> use a library that does, and you aren't required to use access types.
>
> I am required to. There must be always be two types in a GUI, one 
> referential type and one implementation type. The widget implementation 
> object in GtkAda is Gtk_Button_Record. The widget referential object is 
> Gtk_Button. It could be a handle or a smart pointer type instead of plain 
> pointer, but there is no way to reduce it to a single type. So the problem 
> will persist.
>
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de 



^ permalink raw reply	[relevance 7%]

* Re: Type naming conventions: Any_Foo
  2019-12-06 20:18  0%               ` Jeffrey R. Carter
@ 2019-12-06 20:35  0%                 ` Dmitry A. Kazakov
  2019-12-07  0:57  7%                   ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2019-12-06 20:35 UTC (permalink / raw)


On 2019-12-06 21:18, Jeffrey R. Carter wrote:
> On 12/5/19 10:51 PM, Dmitry A. Kazakov wrote:
>>
>> Ada standard library uses _Type, e.g.
>>
>> generic
>>     type Element_Type (<>) is private;
>>     with function "=" (Left, Right : Element_Type) return Boolean is <>;
>> package Ada.Containers.Indefinite_Holders
> 
> Yes, and the ARM also includes such abominations as anonymous access 
> types. Just because it's in the ARM doesn't mean it's the best way to do 
> something. Element is be a better name for that formal type.

No, it would be misleading. Element must be reserved for instances of 
the type. They are actual elements. The type of an element is not an 
element, these are two totally different things.

>> There are lots of cases in Ada, you certainly should know that. As a 
>> practical example GtkAda declares all widget types twice:
>>
>>     type Gtk_Button_Record is ...
>>     type Gtk_Button is access all Gtk_Button_Record'Class;
> 
> No well designed library has public access types. You aren't required to 
> use a library that does, and you aren't required to use access types.

I am required to. There must be always be two types in a GUI, one 
referential type and one implementation type. The widget implementation 
object in GtkAda is Gtk_Button_Record. The widget referential object is 
Gtk_Button. It could be a handle or a smart pointer type instead of 
plain pointer, but there is no way to reduce it to a single type. So the 
problem will persist.

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


^ permalink raw reply	[relevance 0%]

* Re: Type naming conventions: Any_Foo
  2019-12-05 21:51  7%             ` Dmitry A. Kazakov
@ 2019-12-06 20:18  0%               ` Jeffrey R. Carter
  2019-12-06 20:35  0%                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2019-12-06 20:18 UTC (permalink / raw)


On 12/5/19 10:51 PM, Dmitry A. Kazakov wrote:
> 
> Ada standard library uses _Type, e.g.
> 
> generic
>     type Element_Type (<>) is private;
>     with function "=" (Left, Right : Element_Type) return Boolean is <>;
> package Ada.Containers.Indefinite_Holders

Yes, and the ARM also includes such abominations as anonymous access types. Just 
because it's in the ARM doesn't mean it's the best way to do something. Element 
is be a better name for that formal type.

> There are lots of cases in Ada, you certainly should know that. As a practical 
> example GtkAda declares all widget types twice:
> 
>     type Gtk_Button_Record is ...
>     type Gtk_Button is access all Gtk_Button_Record'Class;

No well designed library has public access types. You aren't required to use a 
library that does, and you aren't required to use access types.

-- 
Jeff Carter
"Brave Sir Robin ran away."
Monty Python and the Holy Grail
59

^ permalink raw reply	[relevance 0%]

* Re: Type naming conventions: Any_Foo
  @ 2019-12-05 21:51  7%             ` Dmitry A. Kazakov
  2019-12-06 20:18  0%               ` Jeffrey R. Carter
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2019-12-05 21:51 UTC (permalink / raw)


On 2019-12-05 21:03, Jeffrey R. Carter wrote:
> On 12/5/19 6:45 PM, Dmitry A. Kazakov wrote:
>>
>> 1. Formal generic types. They are customarily named XXX_Type.
> 
> Well chosen names for generic formal types do not end with _Type. The 
> PragmAda Reusable Components have many generic formal types, none of 
> which end with _Type.

Ada standard library uses _Type, e.g.

generic
    type Element_Type (<>) is private;
    with function "=" (Left, Right : Element_Type) return Boolean is <>;
package Ada.Containers.Indefinite_Holders

As I said, the rationale is that there is no meaningful name for 
Element_Type in the problem space. There is no problem space at all. 
Indefinite_Holders is a helper package so general that considered in 
isolation it has no meaning.

>>        -- I don't want access type, I am required to have it
> 
> Please provide examples of being required to have an access type.

There are lots of cases in Ada, you certainly should know that. As a 
practical example GtkAda declares all widget types twice:

    type Gtk_Button_Record is ...
    type Gtk_Button is access all Gtk_Button_Record'Class;

The suffix _Record is an equivalent to _Type.

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


^ permalink raw reply	[relevance 7%]

* yes another gnat bug (inherited tagged type as record field is too much for gnat??)
@ 2019-11-22 13:26  5% gerrshapovalov
  0 siblings, 0 replies; 200+ results
From: gerrshapovalov @ 2019-11-22 13:26 UTC (permalink / raw)


Hello,

This bug gets triggered while trying to use a tiny "list library", that provides a uniform interface for an indexed/iterable storage a-la Ada.Containers.Vectors, that can be implemented in various ways: using A.C.Vecotrs internally or even plain "fixed" or "bounded" arrays..

This "library" is a part of ada_composition demo, now made into a stnandalone library, with tests as separate package, and can be found here:
https://github.com/gerr135/ada_composition

The lib itself is under ada_lists
and tests for the lib are under ada_lists_tests


Everything works just fine,.. - as long as I use these lists as "plain variables". However when such list is uses as a record field, gnat just commits suicide trying to compile it. 

Basically:

with Lists.Fixed;

package PL  is new Lists(Natural, Positive);
package PLF is new PL.Fixed;

LS : PLF.List(5);

type FRec (N : Positive) is record
    f : PLF.List(N);
end record;

LC : FRec(5);


LS(1)   := 1; -- works fine
LC.f(1) := 1; -- triggers gnat bug

+===========================GNAT BUG DETECTED==============================+
| Community 2019 (20190517-83) (x86_64-pc-linux-gnu) Storage_Error stack overflow or erroneous memory access

The code in the "library" is pretty much minimal (needed to implements indexed access and iteration), and the tests are just repeated blocks or basic code to test assignment and iteration (in the form of indexed and of loops).

So, the easiest way to reproduce this should be to just clone the project mentioned above ( https://github.com/gerr135/ada_composition )
and then:
cd ada_lists_tests
make

Quite "weirdly" the stock A.C.Vectors work fine as record fields. However, is this due to
1. them being "proper" types rather than descendants of some interface
2. some ACT black magic in their implementation (they do use locks and Unrestricted_Access) in the corresponding bodies, I looked)
is not quite clear to me..

Am I overlooking something here? 
This should be a really common use case, a very basic composition idea:
1. do all the algorithmic stuff at the "higher level", using abstract data accessor methods
2. Defer data storage and other implementation details to child packages..

Yes every time I am trying to do a very basic separation of this kind I trigger yet another gnat bug :(.

^ permalink raw reply	[relevance 5%]

* Re: how would gnoga.com beat www.tck.tk and postgresql on freebsd?
  2019-11-07 14:21  8%     ` Dmitry A. Kazakov
@ 2019-11-07 23:14  0%       ` Azathoth Hastur
  0 siblings, 0 replies; 200+ results
From: Azathoth Hastur @ 2019-11-07 23:14 UTC (permalink / raw)


On Thursday, November 7, 2019 at 9:21:28 AM UTC-5, Dmitry A. Kazakov wrote:
> On 2019-11-07 14:27, Azathoth Hastur wrote:
> 
> > what are ada containers?
> 
> Ada containers is a part of the standard Ada library. E.g. see the Ada 
> Reference Manual:
> 
>  
> https://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-18.html
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

thank you :)

Interesting!

What books did you learn ada from?

do you use gnoga.com?


^ permalink raw reply	[relevance 0%]

* Re: how would gnoga.com beat www.tck.tk and postgresql on freebsd?
  2019-11-07 13:27  7%   ` Azathoth Hastur
@ 2019-11-07 14:21  8%     ` Dmitry A. Kazakov
  2019-11-07 23:14  0%       ` Azathoth Hastur
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2019-11-07 14:21 UTC (permalink / raw)


On 2019-11-07 14:27, Azathoth Hastur wrote:

> what are ada containers?

Ada containers is a part of the standard Ada library. E.g. see the Ada 
Reference Manual:

 
https://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-18.html

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

^ permalink raw reply	[relevance 8%]

* Re: how would gnoga.com beat www.tck.tk and postgresql on freebsd?
  2019-11-05 17:11  7% ` Shark8
@ 2019-11-07 13:27  7%   ` Azathoth Hastur
  2019-11-07 14:21  8%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Azathoth Hastur @ 2019-11-07 13:27 UTC (permalink / raw)


On Tuesday, November 5, 2019 at 12:11:03 PM UTC-5, Shark8 wrote:
> On Monday, November 4, 2019 at 9:46:02 AM UTC-7, Azathoth Hastur wrote:
> > would it be easier?
> Possibly, because there's [optionally] non-database options... depending on your needs.
> The bindings to databases are exactly the same order of complexity in this regard.
> 
> > faster?
> The Ada.Containers can be used to keep things in memory, and if you're working on small datasets then you likely don't need a database at all. If you can do this, it is faster. / This was the method I used in my bulletin-board site. 
> 
> > fewer errors?
> Yes: Gnoga's DB bindings + migration protocol is *VERY* good for reducing errors. It would be even fewer if I can get NMESON (pure-Ada graph-based database) modernized and integrated into Gnoga.

what are ada containers?


^ permalink raw reply	[relevance 7%]

* Re: how would gnoga.com beat www.tck.tk and postgresql on freebsd?
  @ 2019-11-05 17:11  7% ` Shark8
  2019-11-07 13:27  7%   ` Azathoth Hastur
  0 siblings, 1 reply; 200+ results
From: Shark8 @ 2019-11-05 17:11 UTC (permalink / raw)


On Monday, November 4, 2019 at 9:46:02 AM UTC-7, Azathoth Hastur wrote:
> would it be easier?
Possibly, because there's [optionally] non-database options... depending on your needs.
The bindings to databases are exactly the same order of complexity in this regard.

> faster?
The Ada.Containers can be used to keep things in memory, and if you're working on small datasets then you likely don't need a database at all. If you can do this, it is faster. / This was the method I used in my bulletin-board site. 

> fewer errors?
Yes: Gnoga's DB bindings + migration protocol is *VERY* good for reducing errors. It would be even fewer if I can get NMESON (pure-Ada graph-based database) modernized and integrated into Gnoga.

^ permalink raw reply	[relevance 7%]

* Re: tokyocabinet,redis,mongodb,couchdb,influxdb,timescaledb connectors.
  2019-11-01 13:51  9% ` Shark8
@ 2019-11-01 14:39  0%   ` Alain De Vos
  2022-12-22 13:10  0%   ` Marius Amado-Alves
  1 sibling, 0 replies; 200+ results
From: Alain De Vos @ 2019-11-01 14:39 UTC (permalink / raw)


On Friday, November 1, 2019 at 2:51:27 PM UTC+1, Shark8 wrote:
> On Thursday, October 31, 2019 at 11:18:01 AM UTC-6, Alain De Vos wrote:
> > In our modern time there are also modern databases.
> > But for connecting one needs a connector.
> > I wander to which databases I can connect with ada.
> 
> Apparently GNATCOLL has some database bindings, but I never got them to work. (64bit Windows, 32bit GNAT, 64bit Postgres was my setup back then IIRC; I suspect it had to do with the difference in 32- and 64-bit.)
> 
> I think Dmitry's Simple Components has a ODBC interface.
> 
> And there's an all-Ada graph-database called MNESON that I'm poking at to try to use Ada.Containers rather than the containers it's using.

gnatcoll has normally sqlite and postgres. 
But sqlite,postgres,mysql is the "usual stuff"


^ permalink raw reply	[relevance 0%]

* Re: tokyocabinet,redis,mongodb,couchdb,influxdb,timescaledb connectors.
  @ 2019-11-01 13:51  9% ` Shark8
  2019-11-01 14:39  0%   ` Alain De Vos
  2022-12-22 13:10  0%   ` Marius Amado-Alves
  0 siblings, 2 replies; 200+ results
From: Shark8 @ 2019-11-01 13:51 UTC (permalink / raw)


On Thursday, October 31, 2019 at 11:18:01 AM UTC-6, Alain De Vos wrote:
> In our modern time there are also modern databases.
> But for connecting one needs a connector.
> I wander to which databases I can connect with ada.

Apparently GNATCOLL has some database bindings, but I never got them to work. (64bit Windows, 32bit GNAT, 64bit Postgres was my setup back then IIRC; I suspect it had to do with the difference in 32- and 64-bit.)

I think Dmitry's Simple Components has a ODBC interface.

And there's an all-Ada graph-database called MNESON that I'm poking at to try to use Ada.Containers rather than the containers it's using.

^ permalink raw reply	[relevance 9%]

* Re: How to Iterate over all elements of a hashed_map.
  2019-10-29 15:02  0%   ` joakimds
@ 2019-10-29 21:56  0%     ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2019-10-29 21:56 UTC (permalink / raw)


<joakimds@kth.se> wrote in message 
news:1559a685-7483-4f2f-8674-d7b61c23bfe8@googlegroups.com...
> Den tisdag 29 oktober 2019 kl. 15:20:43 UTC+1 skrev Alain De Vos:
>> I found code which takes a different approach, here there is a function 
>> .Iterate public ... ,
>>
>> with Ada.Containers.Indefinite_Hashed_Maps;
>> with Ada.Strings.Hash;
>>
>> with Ada.Text_IO; use Ada.Text_IO;
>>
>> procedure Show_Hashed_Map is
>>
>>    package Integer_Hashed_Maps is new
>>      Ada.Containers.Indefinite_Hashed_Maps
>>        (Key_Type        => String,
>>         Element_Type    => Integer,
>>         Hash            => Ada.Strings.Hash,
>>         Equivalent_Keys => "=");
>>
>>    use Integer_Hashed_Maps;
>>
>>    M : Map;
>>    --  Same as:  M : Integer_Hashed_Maps.Map;
>> begin
>>    M.Include ("Alice", 24);
>>    M.Include ("John",  40);
>>    M.Include ("Bob",   28);
>>
>>    if M.Contains ("Alice") then
>>       Put_Line ("Alice's age is "
>>                 & Integer'Image (M ("Alice")));
>>    end if;
>>
>>    --  Update Alice's age
>>    --  Key must already exist in M.
>>    --  Otherwise an exception is raised.
>>    M ("Alice") := 25;
>>
>>    New_Line; Put_Line ("Name & Age:");
>>    for C in M.Iterate loop
>>       Put_Line (Key (C) & ": " & Integer'Image (M (C)));
>>    end loop;
>>
>> end Show_Hashed_Map;
>
> I confirm that when you want to iterate over a hashed map and want both 
> key and value you need to use the .Iterate function as you do in the 
> example.

That's the reason it exists, of course. Not everything makes sense just with 
elements alone. (A cursor-based iterator is also much more like the existing 
iteration of Ada 95 than the element-based iterators of Ada 2005 and later.)

                          Randy. 



^ permalink raw reply	[relevance 0%]

* Re: How to Iterate over all elements of a hashed_map.
  2019-10-29 13:43 10% How to Iterate over all elements of a hashed_map Alain De Vos
  2019-10-29 14:20  9% ` Alain De Vos
@ 2019-10-29 16:48  0% ` Jeffrey R. Carter
  1 sibling, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2019-10-29 16:48 UTC (permalink / raw)


On 10/29/19 2:43 PM, Alain De Vos wrote:
> 
>     package My_Hash is new Ada.Containers.Hashed_Maps (Key_Type => Unbounded_String,
>         Element_Type => Unbounded_String,
>         Hash => Hash_Func,
>         Equivalent_Keys => Equivalent_Key);
> 
> But now I want to iterate over all elements of this Hash and print the keys and items ?

My_Hash.Iterate?

-- 
Jeff Carter
"You cheesy lot of second-hand electric donkey-bottom biters."
Monty Python & the Holy Grail
14


^ permalink raw reply	[relevance 0%]

* Re: How to Iterate over all elements of a hashed_map.
  2019-10-29 14:20  9% ` Alain De Vos
@ 2019-10-29 15:02  0%   ` joakimds
  2019-10-29 21:56  0%     ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: joakimds @ 2019-10-29 15:02 UTC (permalink / raw)


Den tisdag 29 oktober 2019 kl. 15:20:43 UTC+1 skrev Alain De Vos:
> I found code which takes a different approach, here there is a function .Iterate public ... ,
> 
> with Ada.Containers.Indefinite_Hashed_Maps;
> with Ada.Strings.Hash;
> 
> with Ada.Text_IO; use Ada.Text_IO;
> 
> procedure Show_Hashed_Map is
> 
>    package Integer_Hashed_Maps is new
>      Ada.Containers.Indefinite_Hashed_Maps
>        (Key_Type        => String,
>         Element_Type    => Integer,
>         Hash            => Ada.Strings.Hash,
>         Equivalent_Keys => "=");
> 
>    use Integer_Hashed_Maps;
> 
>    M : Map;
>    --  Same as:  M : Integer_Hashed_Maps.Map;
> begin
>    M.Include ("Alice", 24);
>    M.Include ("John",  40);
>    M.Include ("Bob",   28);
> 
>    if M.Contains ("Alice") then
>       Put_Line ("Alice's age is "
>                 & Integer'Image (M ("Alice")));
>    end if;
> 
>    --  Update Alice's age
>    --  Key must already exist in M.
>    --  Otherwise an exception is raised.
>    M ("Alice") := 25;
> 
>    New_Line; Put_Line ("Name & Age:");
>    for C in M.Iterate loop
>       Put_Line (Key (C) & ": " & Integer'Image (M (C)));
>    end loop;
> 
> end Show_Hashed_Map;

I confirm that when you want to iterate over a hashed map and want both key and value you need to use the .Iterate function as you do in the example.

Best regards,
Joakim

^ permalink raw reply	[relevance 0%]

* Re: How to Iterate over all elements of a hashed_map.
  2019-10-29 13:43 10% How to Iterate over all elements of a hashed_map Alain De Vos
@ 2019-10-29 14:20  9% ` Alain De Vos
  2019-10-29 15:02  0%   ` joakimds
  2019-10-29 16:48  0% ` Jeffrey R. Carter
  1 sibling, 1 reply; 200+ results
From: Alain De Vos @ 2019-10-29 14:20 UTC (permalink / raw)


I found code which takes a different approach, here there is a function .Iterate public ... ,

with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;

with Ada.Text_IO; use Ada.Text_IO;

procedure Show_Hashed_Map is

   package Integer_Hashed_Maps is new
     Ada.Containers.Indefinite_Hashed_Maps
       (Key_Type        => String,
        Element_Type    => Integer,
        Hash            => Ada.Strings.Hash,
        Equivalent_Keys => "=");

   use Integer_Hashed_Maps;

   M : Map;
   --  Same as:  M : Integer_Hashed_Maps.Map;
begin
   M.Include ("Alice", 24);
   M.Include ("John",  40);
   M.Include ("Bob",   28);

   if M.Contains ("Alice") then
      Put_Line ("Alice's age is "
                & Integer'Image (M ("Alice")));
   end if;

   --  Update Alice's age
   --  Key must already exist in M.
   --  Otherwise an exception is raised.
   M ("Alice") := 25;

   New_Line; Put_Line ("Name & Age:");
   for C in M.Iterate loop
      Put_Line (Key (C) & ": " & Integer'Image (M (C)));
   end loop;

end Show_Hashed_Map;


^ permalink raw reply	[relevance 9%]

* How to Iterate over all elements of a hashed_map.
@ 2019-10-29 13:43 10% Alain De Vos
  2019-10-29 14:20  9% ` Alain De Vos
  2019-10-29 16:48  0% ` Jeffrey R. Carter
  0 siblings, 2 replies; 200+ results
From: Alain De Vos @ 2019-10-29 13:43 UTC (permalink / raw)


I want to use an "associative array" , and have some code for a "string -> string" hash,

with Ada.Containers.Hashed_Maps;
----BEGIN MYHASH
   function Equivalent_Key (Left, Right : Unbounded_String) return Boolean is
   begin
      return Left = Right;
   end Equivalent_Key;
   function Hash_Func (Key : Unbounded_String) return Ada.Containers.Hash_Type is
   begin
      return Ada.Strings.Hash (To_String (Key));
   end Hash_Func;
   package My_Hash is new Ada.Containers.Hashed_Maps (Key_Type => Unbounded_String,
       Element_Type => Unbounded_String,
       Hash => Hash_Func,
       Equivalent_Keys => Equivalent_Key);
----END MYHASH
declare
Hash : My_Hash.Map;
begin
Hash.Insert ( Key => ... , New_Item => ...)
Hash.Insert ( Key => ... , New_Item => ...)

But now I want to iterate over all elements of this Hash and print the keys and items ?


^ permalink raw reply	[relevance 10%]

* Re: How to transfer Class-Wide object to a Task ?
  2019-10-16 20:04  7%       ` William FRANCK
@ 2019-10-17  9:28  9%         ` William FRANCK
  0 siblings, 0 replies; 200+ results
From: William FRANCK @ 2019-10-17  9:28 UTC (permalink / raw)


On 2019-10-16 20:04:41 +0000, William FRANCK said:
 I've uploaded my PoC source file on the comp.lang.ada group.

main_ClassWide_to_2Task.adb

"Transfering Class-Wide Objects to task-entries, with 
Ada.Containers.Indefinite_Holders."

-- ==== here it is as a copy =====
with Ada.Containers.Indefinite_Holders,
     Ada.Text_IO;
use
     Ada,
     Ada.Text_IO;

procedure main_ClassWide_to_2Task is
   -- ========================================================================
   -- Demo program showing how to transfer Class-Wide objects to task-entries,
   -- with Ada.Containers.Indefinite_Holders
   -- ========================================================================
   type Geo2D is tagged record
      Y, X : Integer;
      Name : String (1 .. 8) := "Object 0";
   end record;

   type Circle is new Geo2D with record
      Radius : Integer;
   end record;

   package Geo2D_Holders is new Ada.Containers.Indefinite_Holders 
(Geo2D'Class);

   myDataStore : Geo2D_Holders.Holder;

   -- ==========================================================
   package Object_Reading is

      task reading is
         entry Open;
         entry Object (DataStore : in out Geo2D_Holders.Holder);
         entry Stop;
      end reading;
   end Object_Reading;

   -- ==========================================================
   package Object_Writing is

      task writing is
         entry Create;
         entry Object (DataStore : in Geo2D_Holders.Holder);
         entry Stop;
      end writing;
   end Object_Writing;

   -- ==========================================================
   package body Object_Reading is

      task body reading is
         LocalDataStore : Geo2D_Holders.Holder;
         Nb_items       : Natural := 0;  -- for tracing
      begin
         accept Open do -- end go further only after open is complete
            Text_IO.Put_Line (Standard_Error,"Opening file ...");
         end Open;
         Text_IO.Put_Line (Standard_Error,"Input file ready !");
         loop
            select
               accept Object (DataStore : in out Geo2D_Holders.Holder) do
                  DataStore := Geo2D_Holders.Copy (Source => LocalDataStore);
               end Object;
               declare
                  -- (shortcut to simulate real case with Streams and 
*'Class'Input dispatching) ::
                  --Object : constant Geo2D'Class := Dispatching_Input 
(Ada.Tags.Internal_Tag (External_Tag), Stream);
                  O2D : Geo2D'Class := Circle'(0, 0, "Cercle 0", 10); 
-- simulate object creation done by 'Dispatching_Input'
               begin
                  NB_Items := NB_Items +1; -- for demo
                  O2D.Name(7..8) := Natural'Image(Nb_Items); -- for demo
                  Text_IO.Put_Line (Standard_Error,"Reading 2D Object 
#"& Natural'Image(Nb_Items)&": " & O2D.Name); -- debug trace
                  Geo2D_Holders.Replace_Element (Container => 
LocalDataStore, New_Item => O2D);
               end;
            or
               accept Stop do
                  Text_IO.Put_Line (Standard_Error,"Closing Input file...");
               end Stop;
               Text_IO.Put_Line (Standard_Error,"File cloded, Reading 
Stopped !");
               exit;
            end select;
         end loop;
      end reading;

   end Object_Reading;

   -- ==========================================================
   package body Object_Writing is

      task body writing is

         LocalDataStore : Geo2D_Holders.Holder;
         Nb_items  : Natural := 0;

      begin
         accept Create; -- and go ahead (with i.e. opening input file)
         Text_IO.Put_Line (Standard_Error,"Creating file ...");
         Text_IO.Put_Line (Standard_Error,"Output file ready !");
         loop
            select
               accept Object (DataStore : in Geo2D_Holders.Holder) do
                  LocalDataStore := Geo2D_Holders.copy (DataStore );
               end Object; -- go return to the main process, and go 
ahead with reading next record
               if not Geo2D_Holders.Is_Empty(Container => LocalDataStore)
               then
                  declare
                     O2D : Geo2D'Class := Geo2D_Holders.Element 
(Container => LocalDataStore);
                  begin
                     NB_Items := NB_Items +1; -- for demo
                     --  (shortcut to simulate real case with Streams 
and *'Class'Output dispatching) ::
                     Text_IO.Put_Line (Standard_Error,"   Writing 2D 
Object #"& Natural'Image(Nb_Items)&": " & O2D.Name); -- debug trace
                  end;
               end if;
            or
               accept Stop do
                  Text_IO.Put_Line (Standard_Error,"Closing Output file...");
               end Stop;
               Text_IO.Put_Line (Standard_Error,"File Closed, Writing 
Stopped ! ");
               exit;
            end select;
         end loop;
      end writing;
   end Object_Writing;

   -- ==========================================================
   use Object_Reading;
   use Object_Writing;

begin

   Writing.Create;
   Reading.Open;

   for i in 1 .. 9 loop -- While not end_of_file()
      Reading.Object (myDataStore);
      Writing.Object (myDataStore);
   end loop;

   Reading.Stop;
   Writing.Stop;

end main_ClassWide_to_2Task;


^ permalink raw reply	[relevance 9%]

* Re: How to transfer Class-Wide object to a Task ?
  2019-10-15  4:40 10%     ` Per Sandberg
  2019-10-15  5:40  0%       ` William FRANCK
@ 2019-10-16 20:04  7%       ` William FRANCK
  2019-10-17  9:28  9%         ` William FRANCK
  1 sibling, 1 reply; 200+ results
From: William FRANCK @ 2019-10-16 20:04 UTC (permalink / raw)


Hello Per,

Thaks for the tip !
It saved my life :-).

By using 'Ada.Containers.Indefinite_Holders'
it was possible to transfer the class-wide object from one task-entry 
to another.

If some of you are interested by the 129 SLOC for the sake of sharing designs,
I will post it on this tread.

William.

PS : I didn't found any practical advantage to implement a design with 
a regular FIFO as  the queue will always be at it's max allocation, 
waiting for writing on the file...
Thanks Dmitry for the tip!



On 2019-10-15 04:40:33 +0000, Per Sandberg said:

> Why not use Ada.Containers.Indefinite_holders to encapsulate the 
> Classwide type during store?
> ----------------
> with ADA.Containers.Indefinite_Holders;
> package Demo is
>     type T1 is interface;
>     package T1_Holders is new ADA.Containers.Indefinite_Holders (T1'Class);
> 
>     task type Storage_Task is
>        entry Internal_Store (D : in T1_Holders.Holder);
>        entry Internal_Fetch (D : out T1_Holders.Holder);
>     end Storage_Task;
> 
>     procedure Store (S : Storage_Task; Var : in Demo.T1'Class );
>     Function Fetch(S : Storage_Task) return Demo.T1'Class;
> end Demo;
> ---------------------
> package body Demo is
>     procedure Store (S : Storage_Task; Var : in Demo.T1'Class ) is
>        H : Demo.T1_Holders.Holder;
>     begin
>        H.Replace_Element (Var);
>        S.Internal_Store(H);
>     end Store;
>     Function Fetch(S : Storage_Task) return Demo.T1'Class is
>        H : Demo.T1_Holders.Holder;
>     begin
>        S.Internal_Fetch (H);
>        return H.Element;
>     end Fetch;
> 
>     task body Storage_Task is
>        S : T1_Holders.Holder;
>     begin
>        loop
>           select
>              accept Internal_Fetch (D : out T1_Holders.Holder)  do
>                 D := S;
>              end Internal_Fetch;
>           or accept Internal_Store (D : in T1_Holders.Holder) do
>                 S := D;
>              end Internal_Store;
>           or
>              terminate;
>           end select;
>        end loop;
>     end Storage_Task;
> end Demo;
> ---------------------
> /P
> 
> On 2019-10-14 22:58, William FRANCK wrote:
>> On 2019-10-14 19:58:34 +0000, Dmitry A. Kazakov said:
>> 
>>> On 2019-10-14 21:41, William FRANCK wrote:
>>> 
>>>> Here is a nice issue I have with Ada (GNAT 2012) when trying to do OO 
>>>> dispatching with streams in different tasks ...
>>>> 
>>>> Here it is :
>>>> I'd like to get from a task RdV (Entry-Access) an object which could be 
>>>> any subclass of a root'Class, and pass it to another task
>>>> 
>>>> Context : read (Root'Class'Input() ) tagged records from an input 
>>>> stream, and send them to anther task which will write 
>>>> (Root'Class'Output() ) the given records to another output stream.
>>> 
>>> Strange design, why not to pipe streams using a FIFO?
>>> 
>>>> I'm stuck with task memory isolation with does NOT allow to pass any 
>>>> access object to a Root'Class.
>>>> 
>>>> Should I try to use a protected object ?
>>>> (not shore this solves the passing of a Class-wide object ...)
>>> 
>>> Yes, if using FIFO, a protected object can be used to signal 
>>> non-empty/not-full events at the FIFO ends.
>>> 
>>> Otherwise, use a reference-counted handle or a plain access type to the 
>>> target object. The reader task allocates the object in the pool and 
>>> passes a handle or access to it to the writer. The writer task writes 
>>> the object and then disposes it.
>> 
>> Thanks you Dimitry for your follow-up.
>> 
>> Here is the multitasking part (simplified) (working, no issue)
>> for reading the datafile, and writing it back (after some data-process)
>> 
>> My first intention was : while Writing.Bloc is busy writing on the 
>> output file, Reading.Bloc can take 1 record in advance
>> 
>> Now I have to insert the class-wide object passing in the Bloc.
>> 
>> As You mentionned, should I use a protected type (FIFO)  instead of 2 
>> // tasks ?
>> 
>> --================
>> with Ada.Text_io;
>> 
>> procedure main_tasks is
>> 
>>   task reading is
>>      entry Open;
>>      entry Bloc;
>>      entry Stop;
>>   end reading;
>> 
>>   task  writing is
>>      entry Create;
>>      entry Bloc;
>>      entry Stop;
>>   end writing;
>> 
>>   task body reading is
>>   begin
>>      loop
>>         select
>>            accept Open;
>>               Ada.Text_IO.put_line("Opening file ...");
>>         or
>>            accept Bloc do
>>               Ada.Text_IO.put_line("Reading ...");
>>            end Bloc;
>>         or
>>            accept Stop;
>>            Ada.Text_IO.put_line("Reading Stopped !");
>>            exit;
>>         end select;
>>      end loop;
>>   end reading;
>> 
>>   task body writing is
>>   begin
>>      loop
>>      select
>>         accept Create;
>>         Ada.Text_IO.put_line("Creating file ...");
>>         or
>>            accept Bloc do
>>               Ada.Text_IO.put_line("Got bloc !");
>>            end Bloc;
>>            Ada.Text_IO.put_line("Writing bloc ...");
>>         or
>>            accept Stop;
>>            Ada.Text_IO.put_line("Writing Stopped !");
>>            exit;
>>         end select;
>>      end loop;
>>   end writing;
>> 
>> begin
>> 
>>   Writing.Create;
>>   Reading.Open;
>>   for i in 1..10 loop -- While not end_of_file()
>>      Reading.Bloc;
>>      Writing.Bloc;
>>   end loop;
>> 
>>   Reading.Stop;
>>   Writing.Stop;
>> 
>> end main_tasks;


^ permalink raw reply	[relevance 7%]

* Re: How to transfer Class-Wide object to a Task ?
  @ 2019-10-15 19:41  6%       ` William FRANCK
  0 siblings, 0 replies; 200+ results
From: William FRANCK @ 2019-10-15 19:41 UTC (permalink / raw)


Thank you Optikas for your feedback and advice :-)

Sure, the usual design of a multithreaded  'producer' and 'consumer' 
takes advantage of a FIFO round.
I will considering and testing this as Dmitry outlined it for me.

In fact I may considering my design as a FIFO of one (1) (lol) ?

For now I'm implementing the 'Ada.Containers.Indefinite_Holders' in a 
little PoC.
I'l will share this to the group.

As I mentionned, I do use the Stream attributes 'Input and 'Output, and 
is OK in one single program. The challenge for me is to make it work 
(and pass the objects) in a multi-tasking design.

Huh ?!? There is still something to learn about class-wide and 
indefinite type usage :-)


By the way, I really appreciate the support of this group !
Kind regards,
William



On 2019-10-15 14:31:30 +0000, Optikos said:

> On Tuesday, October 15, 2019 at 2:21:51 AM UTC-5, Dmitry A. Kazakov wrote:
>> On 2019-10-14 22:58, William FRANCK wrote:
>> 
>>> Here is the multitasking part (simplified) (working, no issue)
>>> for reading the datafile, and writing it back (after some data-process)
>>> 
>>> My first intention was : while Writing.Bloc is busy writing on the> > 
>>> output file, Reading.Bloc can take 1 record in advance
>> 
>> That is what OS asynchronous I/O does already. But that is aside.
>> 
>>> Now I have to insert the class-wide object passing in the Bloc.
>> 
>> Stream attributes 'Input and 'Output would do.
>> 
>>> As You mentionned, should I use a protected type (FIFO)  instead of 2 
>>> //> > tasks ?
>> 
>> A protected object to synchronize two tasks:
>> 
>> Producer -> FIFO -> Consumer
>> Block put <- PO -> Block get
>> when full          when empty
>> 
>> FIFO does not need interlocking in this scenario. Protected object is> 
>> only to prevent busy waiting at the ends.
>> 
>> Since you are working with streams you can use a storage stream 
>> instead> of raw FIFO:
>> 
>> Producer -> Storage stream -> Consumer
>> Block write when full    Block read when empty
>> 
>> I still do not understand why you serialize and deserialize insted of> 
>> copying bytes as they are.
> 
> Because OPer is apparently migrating code that was in 2 (UNIXesque) 
> processes to instead be 2 threads in the same process.
> 
> William Franck, you really should rework your design to do as Dmitry 
> advises:  FIFO message queues between 2 otherwise asynchronous threads 
> that work on their own slice of the problem (and have their own slice 
> of the problem's data structures).  Under that revised design, only the 
> FIFO's internals need to worry about thread safety, because before 
> posting and after retrieving from the queue the 2 threads run full tilt 
> in their independent territory without interacting with each other.  
> (This of course assumes that there exists some sort of 
> slicing/partitioning of your problem-space, but there usually is if you 
> look intensely enough for well-defined demarcations.)


^ permalink raw reply	[relevance 6%]

* Re: How to transfer Class-Wide object to a Task ?
  2019-10-14 21:57  6%   ` Shark8
@ 2019-10-15  5:43  0%     ` William FRANCK
  0 siblings, 0 replies; 200+ results
From: William FRANCK @ 2019-10-15  5:43 UTC (permalink / raw)


Thank you Shark,
I'll give it a try too :-)

And send you all a more complete source code of my use case.

William


On 2019-10-14 21:57:57 +0000, Shark8 said:


> On Monday, October 14, 2019 at 2:21:50 PM UTC-6, William FRANCK wrote:
>> On 2019-10-14 19:41:53 +0000, William FRANCK said:
>> 
> Maybe something like this:
> 
>     procedure Example is
>         Package Types is
>             Subtype Params is Ada.Streams.Root_Stream_Type'Class;
>             Type Root   is abstract tagged null record;
>             Function Create (Parameters : not null access Params) 
> return Root is abstract;
> 
>             Type Circle is new Root with record
>                 Radius : Float;
>             end record;
> 
>             Type Square is new Root with record
>                 Side : Integer;
>             end record;
>         Private
> 
>             Function Create (Parameters : not null access Params) 
> return Square;
>             Function Create (Parameters : not null access Params) 
> return Circle;
>         End Types;
> 
> 
>         Use Types;
>         Package Class_Holder is new 
> Ada.Containers.Indefinite_Holders(Root'Class);
>         Task Type Producer( Stream : not null access 
> Ada.Streams.Root_Stream_Type'Class ) is
>             Entry Get( Object: out Class_Holder.Holder );
>         End Producer;
> 
>         Task body Producer is
>             Function MAKE is new Ada.Tags.Generic_Dispatching_Constructor(
>                T           => Types.Root,
>                Parameters  => Ada.Streams.Root_Stream_Type'Class,
>                Constructor => Types.Create
>               );
> 
>             Function To_Tag return Ada.Tags.Tag is
>             Begin
>                 Return Square'Tag;
> --                  (if    Ch = 'C' then Circle'Tag
> --                   elsif Ch = 'S' then Square'Tag
> --                   else raise Constraint_Error with "Tag '"&Ch&"' is 
> invalid.");
>             End;
> 
>         Begin
>             accept Get (Object : out Class_Holder.Holder) do
>                 Object:=
>                   Class_Holder.To_Holder( MAKE(To_Tag, Stream) );
>             end Get;
>         end Producer;
> 
>         Function Get(P : Producer) return Root'Class is
>             H : Class_Holder.Holder;
>         Begin
>             P.Get(H);
>             Return H.Element;
>         End Get;
> 
> 
> 
>         Package Body Types is
>             Function Create(Parameters : not null access Params) return 
> Square is
>             Begin
>                 Return (Side => 3);
>             End;
> 
>             Function Create(Parameters : not null access Params) return 
> Circle is
>             Begin
>                 Return (Radius => 2.2);
>             End;
>         End Types;
> 
>     begin
>         Ada.Text_IO.Put_Line( "START EXAMPLE." );
>         declare
>             I : Ada.Text_IO.File_Type renames Ada.Text_IO.Standard_Input;
>             P : Producer( Ada.Text_IO.Text_Streams.Stream(I) );
>             O : Root'Class := Get(P);
>         begin
>             Ada.Text_IO.Put_Line( "Tag: " & Ada.Tags.Expanded_Name(O'Tag) );
>         end;
>         Ada.Text_IO.Put_Line( "STOP EXAMPLE." );
>     end Example;


^ permalink raw reply	[relevance 0%]

* Re: How to transfer Class-Wide object to a Task ?
  2019-10-15  4:40 10%     ` Per Sandberg
@ 2019-10-15  5:40  0%       ` William FRANCK
  2019-10-16 20:04  7%       ` William FRANCK
  1 sibling, 0 replies; 200+ results
From: William FRANCK @ 2019-10-15  5:40 UTC (permalink / raw)


Thanks Per !

"Containers.Indefinite_holders" seems to be the way to go.
(I didn't used them yet)
I will give it a try :-)

William.

On 2019-10-15 04:40:33 +0000, Per Sandberg said:

> Why not use Ada.Containers.Indefinite_holders to encapsulate the 
> Classwide type during store?
> ----------------
> with ADA.Containers.Indefinite_Holders;
> package Demo is
>     type T1 is interface;
>     package T1_Holders is new ADA.Containers.Indefinite_Holders (T1'Class);
> 
>     task type Storage_Task is
>        entry Internal_Store (D : in T1_Holders.Holder);
>        entry Internal_Fetch (D : out T1_Holders.Holder);
>     end Storage_Task;
> 
>     procedure Store (S : Storage_Task; Var : in Demo.T1'Class );
>     Function Fetch(S : Storage_Task) return Demo.T1'Class;
> end Demo;
> ---------------------
> package body Demo is
>     procedure Store (S : Storage_Task; Var : in Demo.T1'Class ) is
>        H : Demo.T1_Holders.Holder;
>     begin
>        H.Replace_Element (Var);
>        S.Internal_Store(H);
>     end Store;
>     Function Fetch(S : Storage_Task) return Demo.T1'Class is
>        H : Demo.T1_Holders.Holder;
>     begin
>        S.Internal_Fetch (H);
>        return H.Element;
>     end Fetch;
> 
>     task body Storage_Task is
>        S : T1_Holders.Holder;
>     begin
>        loop
>           select
>              accept Internal_Fetch (D : out T1_Holders.Holder)  do
>                 D := S;
>              end Internal_Fetch;
>           or accept Internal_Store (D : in T1_Holders.Holder) do
>                 S := D;
>              end Internal_Store;
>           or
>              terminate;
>           end select;
>        end loop;
>     end Storage_Task;
> end Demo;
> ---------------------
> /P
> 
> On 2019-10-14 22:58, William FRANCK wrote:
>> On 2019-10-14 19:58:34 +0000, Dmitry A. Kazakov said:
>> 
>>> On 2019-10-14 21:41, William FRANCK wrote:
>>> 
>>>> Here is a nice issue I have with Ada (GNAT 2012) when trying to do OO 
>>>> dispatching with streams in different tasks ...
>>>> 
>>>> Here it is :
>>>> I'd like to get from a task RdV (Entry-Access) an object which could be 
>>>> any subclass of a root'Class, and pass it to another task
>>>> 
>>>> Context : read (Root'Class'Input() ) tagged records from an input 
>>>> stream, and send them to anther task which will write 
>>>> (Root'Class'Output() ) the given records to another output stream.
>>> 
>>> Strange design, why not to pipe streams using a FIFO?
>>> 
>>>> I'm stuck with task memory isolation with does NOT allow to pass any 
>>>> access object to a Root'Class.
>>>> 
>>>> Should I try to use a protected object ?
>>>> (not shore this solves the passing of a Class-wide object ...)
>>> 
>>> Yes, if using FIFO, a protected object can be used to signal 
>>> non-empty/not-full events at the FIFO ends.
>>> 
>>> Otherwise, use a reference-counted handle or a plain access type to the 
>>> target object. The reader task allocates the object in the pool and 
>>> passes a handle or access to it to the writer. The writer task writes 
>>> the object and then disposes it.
>> 
>> Thanks you Dimitry for your follow-up.
>> 
>> Here is the multitasking part (simplified) (working, no issue)
>> for reading the datafile, and writing it back (after some data-process)
>> 
>> My first intention was : while Writing.Bloc is busy writing on the 
>> output file, Reading.Bloc can take 1 record in advance
>> 
>> Now I have to insert the class-wide object passing in the Bloc.
>> 
>> As You mentionned, should I use a protected type (FIFO)  instead of 2 
>> // tasks ?
>> 
>> --================
>> with Ada.Text_io;
>> 
>> procedure main_tasks is
>> 
>>   task reading is
>>      entry Open;
>>      entry Bloc;
>>      entry Stop;
>>   end reading;
>> 
>>   task  writing is
>>      entry Create;
>>      entry Bloc;
>>      entry Stop;
>>   end writing;
>> 
>>   task body reading is
>>   begin
>>      loop
>>         select
>>            accept Open;
>>               Ada.Text_IO.put_line("Opening file ...");
>>         or
>>            accept Bloc do
>>               Ada.Text_IO.put_line("Reading ...");
>>            end Bloc;
>>         or
>>            accept Stop;
>>            Ada.Text_IO.put_line("Reading Stopped !");
>>            exit;
>>         end select;
>>      end loop;
>>   end reading;
>> 
>>   task body writing is
>>   begin
>>      loop
>>      select
>>         accept Create;
>>         Ada.Text_IO.put_line("Creating file ...");
>>         or
>>            accept Bloc do
>>               Ada.Text_IO.put_line("Got bloc !");
>>            end Bloc;
>>            Ada.Text_IO.put_line("Writing bloc ...");
>>         or
>>            accept Stop;
>>            Ada.Text_IO.put_line("Writing Stopped !");
>>            exit;
>>         end select;
>>      end loop;
>>   end writing;
>> 
>> begin
>> 
>>   Writing.Create;
>>   Reading.Open;
>>   for i in 1..10 loop -- While not end_of_file()
>>      Reading.Bloc;
>>      Writing.Bloc;
>>   end loop;
>> 
>>   Reading.Stop;
>>   Writing.Stop;
>> 
>> end main_tasks;



^ permalink raw reply	[relevance 0%]

* Re: How to transfer Class-Wide object to a Task ?
  @ 2019-10-15  4:40 10%     ` Per Sandberg
  2019-10-15  5:40  0%       ` William FRANCK
  2019-10-16 20:04  7%       ` William FRANCK
    1 sibling, 2 replies; 200+ results
From: Per Sandberg @ 2019-10-15  4:40 UTC (permalink / raw)


Why not use Ada.Containers.Indefinite_holders to encapsulate the 
Classwide type during store?
----------------
with ADA.Containers.Indefinite_Holders;
package Demo is
    type T1 is interface;
    package T1_Holders is new ADA.Containers.Indefinite_Holders (T1'Class);

    task type Storage_Task is
       entry Internal_Store (D : in T1_Holders.Holder);
       entry Internal_Fetch (D : out T1_Holders.Holder);
    end Storage_Task;

    procedure Store (S : Storage_Task; Var : in Demo.T1'Class );
    Function Fetch(S : Storage_Task) return Demo.T1'Class;
end Demo;
---------------------
package body Demo is
    procedure Store (S : Storage_Task; Var : in Demo.T1'Class ) is
       H : Demo.T1_Holders.Holder;
    begin
       H.Replace_Element (Var);
       S.Internal_Store(H);
    end Store;
    Function Fetch(S : Storage_Task) return Demo.T1'Class is
       H : Demo.T1_Holders.Holder;
    begin
       S.Internal_Fetch (H);
       return H.Element;
    end Fetch;

    task body Storage_Task is
       S : T1_Holders.Holder;
    begin
       loop
          select
             accept Internal_Fetch (D : out T1_Holders.Holder)  do
                D := S;
             end Internal_Fetch;
          or accept Internal_Store (D : in T1_Holders.Holder) do
                S := D;
             end Internal_Store;
          or
             terminate;
          end select;
       end loop;
    end Storage_Task;
end Demo;
---------------------
/P

On 2019-10-14 22:58, William FRANCK wrote:
> On 2019-10-14 19:58:34 +0000, Dmitry A. Kazakov said:
> 
>> On 2019-10-14 21:41, William FRANCK wrote:
>>
>>> Here is a nice issue I have with Ada (GNAT 2012) when trying to do OO 
>>> dispatching with streams in different tasks ...
>>>
>>> Here it is :
>>> I'd like to get from a task RdV (Entry-Access) an object which could 
>>> be any subclass of a root'Class, and pass it to another task
>>>
>>> Context : read (Root'Class'Input() ) tagged records from an input 
>>> stream, and send them to anther task which will write 
>>> (Root'Class'Output() ) the given records to another output stream.
>>
>> Strange design, why not to pipe streams using a FIFO?
>>
>>> I'm stuck with task memory isolation with does NOT allow to pass any 
>>> access object to a Root'Class.
>>>
>>> Should I try to use a protected object ?
>>> (not shore this solves the passing of a Class-wide object ...)
>>
>> Yes, if using FIFO, a protected object can be used to signal 
>> non-empty/not-full events at the FIFO ends.
>>
>> Otherwise, use a reference-counted handle or a plain access type to 
>> the target object. The reader task allocates the object in the pool 
>> and passes a handle or access to it to the writer. The writer task 
>> writes the object and then disposes it.
> 
> Thanks you Dimitry for your follow-up.
> 
> Here is the multitasking part (simplified) (working, no issue)
> for reading the datafile, and writing it back (after some data-process)
> 
> My first intention was : while Writing.Bloc is busy writing on the 
> output file, Reading.Bloc can take 1 record in advance
> 
> Now I have to insert the class-wide object passing in the Bloc.
> 
> As You mentionned, should I use a protected type (FIFO)  instead of 2 // 
> tasks ?
> 
> --================
> with Ada.Text_io;
> 
> procedure main_tasks is
> 
>    task reading is
>       entry Open;
>       entry Bloc;
>       entry Stop;
>    end reading;
> 
>    task  writing is
>       entry Create;
>       entry Bloc;
>       entry Stop;
>    end writing;
> 
>    task body reading is
>    begin
>       loop
>          select
>             accept Open;
>                Ada.Text_IO.put_line("Opening file ...");
>          or
>             accept Bloc do
>                Ada.Text_IO.put_line("Reading ...");
>             end Bloc;
>          or
>             accept Stop;
>             Ada.Text_IO.put_line("Reading Stopped !");
>             exit;
>          end select;
>       end loop;
>    end reading;
> 
>    task body writing is
>    begin
>       loop
>       select
>          accept Create;
>          Ada.Text_IO.put_line("Creating file ...");
>          or
>             accept Bloc do
>                Ada.Text_IO.put_line("Got bloc !");
>             end Bloc;
>             Ada.Text_IO.put_line("Writing bloc ...");
>          or
>             accept Stop;
>             Ada.Text_IO.put_line("Writing Stopped !");
>             exit;
>          end select;
>       end loop;
>    end writing;
> 
> begin
> 
>    Writing.Create;
>    Reading.Open;
>    for i in 1..10 loop -- While not end_of_file()
>       Reading.Bloc;
>       Writing.Bloc;
>    end loop;
> 
>    Reading.Stop;
>    Writing.Stop;
> 
> end main_tasks;
> 


^ permalink raw reply	[relevance 10%]

* Re: How to transfer Class-Wide object to a Task ?
  @ 2019-10-14 21:57  6%   ` Shark8
  2019-10-15  5:43  0%     ` William FRANCK
  0 siblings, 1 reply; 200+ results
From: Shark8 @ 2019-10-14 21:57 UTC (permalink / raw)


On Monday, October 14, 2019 at 2:21:50 PM UTC-6, William FRANCK wrote:
> On 2019-10-14 19:41:53 +0000, William FRANCK said:
> 
Maybe something like this:

    procedure Example is
        Package Types is
            Subtype Params is Ada.Streams.Root_Stream_Type'Class;
            Type Root   is abstract tagged null record;
            Function Create (Parameters : not null access Params) return Root is abstract;
            
            Type Circle is new Root with record
                Radius : Float;
            end record;
            
            Type Square is new Root with record
                Side : Integer;
            end record;
        Private
            
            Function Create (Parameters : not null access Params) return Square;
            Function Create (Parameters : not null access Params) return Circle;
        End Types;
        
        
        Use Types;
        Package Class_Holder is new Ada.Containers.Indefinite_Holders(Root'Class);
        Task Type Producer( Stream : not null access Ada.Streams.Root_Stream_Type'Class ) is
            Entry Get( Object: out Class_Holder.Holder );
        End Producer;
        
        Task body Producer is
            Function MAKE is new Ada.Tags.Generic_Dispatching_Constructor(
               T           => Types.Root,
               Parameters  => Ada.Streams.Root_Stream_Type'Class,
               Constructor => Types.Create
              );

            Function To_Tag return Ada.Tags.Tag is
            Begin
                Return Square'Tag;
--                  (if    Ch = 'C' then Circle'Tag
--                   elsif Ch = 'S' then Square'Tag
--                   else raise Constraint_Error with "Tag '"&Ch&"' is invalid.");
            End;
            
        Begin
            accept Get (Object : out Class_Holder.Holder) do
                Object:=
                  Class_Holder.To_Holder( MAKE(To_Tag, Stream) );
            end Get;
        end Producer;
        
        Function Get(P : Producer) return Root'Class is
            H : Class_Holder.Holder;
        Begin
            P.Get(H);
            Return H.Element;
        End Get;
        
        
        
        Package Body Types is
            Function Create(Parameters : not null access Params) return Square is
            Begin
                Return (Side => 3);
            End;
            
            Function Create(Parameters : not null access Params) return Circle is
            Begin
                Return (Radius => 2.2);
            End;
        End Types;
        
    begin
        Ada.Text_IO.Put_Line( "START EXAMPLE." );
        declare
            I : Ada.Text_IO.File_Type renames Ada.Text_IO.Standard_Input;
            P : Producer( Ada.Text_IO.Text_Streams.Stream(I) );
            O : Root'Class := Get(P);
        begin
            Ada.Text_IO.Put_Line( "Tag: " & Ada.Tags.Expanded_Name(O'Tag) );
        end;
        Ada.Text_IO.Put_Line( "STOP EXAMPLE." );
    end Example;

^ permalink raw reply	[relevance 6%]

* Funny (so to say...) interaction of "not null" and Vectors?
@ 2019-10-08 15:46  6% mockturtle
  0 siblings, 0 replies; 200+ results
From: mockturtle @ 2019-10-08 15:46 UTC (permalink / raw)


Dear.all,
I am getting crazy over a mysterious bug (that gives mysterious exceptions) that seems to boil down to an interaction between "not null" specification and vectors.

This is an over simplified version of my case.  I would like to know if my hypothesis makes sense.

---  BEGIN ----
type Int is interface;
type Class_Access is not null access all Int'Class;  --  NOTE: not null

type Rec is -- A record with a not null component
  record 
     Acc : Class_Access;  -- This forces me to initialize it
  end record; 

package Vec is new Ada.Containers.Vectors(Positive, Rec);  
-- Vectors that have as elements records with a "not null access" field
--- END ---

It seems that the procedure Append from Vec dies with a "access check failed."  By looking into the GNAT implementation, I see that the Vector is implemented using a dynamically allocated array of Rec (in this case).  When I do Append, the procedure re-allocate the array to make room for the new entry.  My suspect is that the dynamically created array can have some null access value, causing the error.

Does this make any sense?  If yes, I'll remove the "not null" requirement.

Thank you in advance 

Riccardo 

^ permalink raw reply	[relevance 6%]

* Re: Graph database client? eg Neo4j, Dgraph ...
  2018-12-15  0:59  0%   ` Olivier Henley
  2018-12-16 18:23  7%     ` Shark8
@ 2019-08-20 15:13  0%     ` Shark8
  2022-12-22 13:16  0%       ` Marius Amado-Alves
  1 sibling, 1 reply; 200+ results
From: Shark8 @ 2019-08-20 15:13 UTC (permalink / raw)


On Friday, December 14, 2018 at 6:00:00 PM UTC-7, Olivier Henley wrote:
> On Thursday, December 13, 2018 at 6:15:08 PM UTC-5, Shark8 wrote:
> > On Wednesday, December 12, 2018 at 7:04:15 AM UTC-7, Olivier Henley wrote:
> > > Hi to all,
> > > 
> > > Anyone knows of an initiative at providing a Neo4j() Ada client? Or any other graph db really...
> > 
> > There is/was an all-Ada graph-DB called Mneson -- Archived here: https://web.archive.org/web/20070625173813/http://www.liacc.up.pt/~maa/mneson/ -- of which I have a copy of two versions. I was trying to translate them so that instead of the containers dependency ["Charles Containers", IIRC] they would use the Ada.Containers.* packages instead.
> 
> Thx! I communicated with the author to bring this code on github. More to come.

Did the code ever make it to github?
Did anything else ever happen here?

^ permalink raw reply	[relevance 0%]

* Re: recursive map specification
  2019-06-25  9:22  0%     ` Egil H H
@ 2019-06-25  9:24  0%       ` mario.blunk.gplus
  0 siblings, 0 replies; 200+ results
From: mario.blunk.gplus @ 2019-06-25  9:24 UTC (permalink / raw)


On Tuesday, June 25, 2019 at 11:22:25 AM UTC+2, Egil H H wrote:
> On Tuesday, June 25, 2019 at 11:09:20 AM UTC+2, mario.b...@gmail.com wrote:
> > On Tuesday, June 25, 2019 at 10:44:11 AM UTC+2, Egil H H wrote:
> > > On Tuesday, June 25, 2019 at 10:21:03 AM UTC+2, mario.b...@gmail.com wrote:
> > > > Hello,
> > > > 
> > > > I want to specify a recursive map. To simplify the problem I use the example of a person and its ancestors and ancestors ... The problem does not seem special but I haven't found a solution. The approach below does not compile:
> > > > 
> > > > type person is record
> > > >  name : unbounded_string;
> > > > end record;
> > > > 
> > > > package tree is new ordered_maps 
> > > >  (
> > > >  key_type => person,
> > > >  element_type => tree.map -- compiler error. "tree" undefined
> > > >  );
> > > > 
> > > > Any ideas ? Thanks a lot !
> > > 
> > > 
> > > Is there a reason you don't use Ada.Containers.Multiway_Trees instead?
> > > 
> > > 
> > > -- 
> > > ~egilhh
> > 
> > It is the first time I read about multiway_trees. Do you have a simple example ready ? Otherwise I would dig into the package docs which lack practical examples... Thanks
> 
> 
> Sorry, I haven't used that package myself, but there's some additional explanation and example in the Rationale, http://www.ada-auth.org/standards/12rat/html/Rat12-8-4.html
> 
> 
> -- 
> ~egilhh

Yep, I just found that too. Thanks. Time for reading :-)


^ permalink raw reply	[relevance 0%]

* Re: recursive map specification
  2019-06-25  9:09  0%   ` mario.blunk.gplus
@ 2019-06-25  9:22  0%     ` Egil H H
  2019-06-25  9:24  0%       ` mario.blunk.gplus
  0 siblings, 1 reply; 200+ results
From: Egil H H @ 2019-06-25  9:22 UTC (permalink / raw)


On Tuesday, June 25, 2019 at 11:09:20 AM UTC+2, mario.b...@gmail.com wrote:
> On Tuesday, June 25, 2019 at 10:44:11 AM UTC+2, Egil H H wrote:
> > On Tuesday, June 25, 2019 at 10:21:03 AM UTC+2, mario.b...@gmail.com wrote:
> > > Hello,
> > > 
> > > I want to specify a recursive map. To simplify the problem I use the example of a person and its ancestors and ancestors ... The problem does not seem special but I haven't found a solution. The approach below does not compile:
> > > 
> > > type person is record
> > >  name : unbounded_string;
> > > end record;
> > > 
> > > package tree is new ordered_maps 
> > >  (
> > >  key_type => person,
> > >  element_type => tree.map -- compiler error. "tree" undefined
> > >  );
> > > 
> > > Any ideas ? Thanks a lot !
> > 
> > 
> > Is there a reason you don't use Ada.Containers.Multiway_Trees instead?
> > 
> > 
> > -- 
> > ~egilhh
> 
> It is the first time I read about multiway_trees. Do you have a simple example ready ? Otherwise I would dig into the package docs which lack practical examples... Thanks


Sorry, I haven't used that package myself, but there's some additional explanation and example in the Rationale, http://www.ada-auth.org/standards/12rat/html/Rat12-8-4.html


-- 
~egilhh

^ permalink raw reply	[relevance 0%]

* Re: recursive map specification
  2019-06-25  8:44  7% ` Egil H H
@ 2019-06-25  9:09  0%   ` mario.blunk.gplus
  2019-06-25  9:22  0%     ` Egil H H
  0 siblings, 1 reply; 200+ results
From: mario.blunk.gplus @ 2019-06-25  9:09 UTC (permalink / raw)


On Tuesday, June 25, 2019 at 10:44:11 AM UTC+2, Egil H H wrote:
> On Tuesday, June 25, 2019 at 10:21:03 AM UTC+2, mario.b...@gmail.com wrote:
> > Hello,
> > 
> > I want to specify a recursive map. To simplify the problem I use the example of a person and its ancestors and ancestors ... The problem does not seem special but I haven't found a solution. The approach below does not compile:
> > 
> > type person is record
> >  name : unbounded_string;
> > end record;
> > 
> > package tree is new ordered_maps 
> >  (
> >  key_type => person,
> >  element_type => tree.map -- compiler error. "tree" undefined
> >  );
> > 
> > Any ideas ? Thanks a lot !
> 
> 
> Is there a reason you don't use Ada.Containers.Multiway_Trees instead?
> 
> 
> -- 
> ~egilhh

It is the first time I read about multiway_trees. Do you have a simple example ready ? Otherwise I would dig into the package docs which lack practical examples... Thanks

^ permalink raw reply	[relevance 0%]

* Re: recursive map specification
  @ 2019-06-25  8:44  7% ` Egil H H
  2019-06-25  9:09  0%   ` mario.blunk.gplus
  0 siblings, 1 reply; 200+ results
From: Egil H H @ 2019-06-25  8:44 UTC (permalink / raw)


On Tuesday, June 25, 2019 at 10:21:03 AM UTC+2, mario.b...@gmail.com wrote:
> Hello,
> 
> I want to specify a recursive map. To simplify the problem I use the example of a person and its ancestors and ancestors ... The problem does not seem special but I haven't found a solution. The approach below does not compile:
> 
> type person is record
>  name : unbounded_string;
> end record;
> 
> package tree is new ordered_maps 
>  (
>  key_type => person,
>  element_type => tree.map -- compiler error. "tree" undefined
>  );
> 
> Any ideas ? Thanks a lot !


Is there a reason you don't use Ada.Containers.Multiway_Trees instead?


-- 
~egilhh

^ permalink raw reply	[relevance 7%]

* Re: Intervention needed?
  2019-03-29 22:35  7%                       ` Florian Weimer
@ 2019-04-01 21:17  0%                         ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2019-04-01 21:17 UTC (permalink / raw)


"Florian Weimer" <fw@deneb.enyo.de> wrote in message 
news:87zhpdgvhl.fsf@mid.deneb.enyo.de...
>* Randy Brukardt:
>
>>>"Florian Weimer" <fw@deneb.enyo.de> wrote in message
>>>news:87sgv5k1j5.fsf@mid.deneb.enyo.de...
>>>* Randy Brukardt:
>>>
>>>> But a better question is whether the Rust borrow checker allows
>>>> building proper ADTs for most data structures.
>>>
>>> The Rust standard library uses unsafe extensively in the
>>> implementation of containers.  I'm not sure if this is a problem.
>>> Most languages have this property (that the standard library cannot be
>>> implemented in the language itself).
>>>
>>> For container libraries, the only widely-used counter-example (of
>>> which I'm aware) is pre-generic Java.
>>
>> You're saying Ada isn't widely used? And I thought the STL was 
>> implemented
>> in C++.
>
> The GNAT implementation doesn't seem particularly memory-safe to me,
> looking at Ada.Containers.Bounded_Ordered_Maps (which picked more or
> less at random).

You said "Most languages have this property (that the standard library 
cannot be implemented in the language itself)." You didn't say anything 
about memory safety -- and it wouldn't make sense anyway, since most 
languages don't have "memory safety" (whatever that is) in the first place.

For Ada, the entire idea of the containers was to allow implementations to 
have as much (or as little) memory safety as they want. There's none that an 
implementation can provide with access types.

                               Randy. 



^ permalink raw reply	[relevance 0%]

* Re: Intervention needed?
  @ 2019-03-29 22:35  7%                       ` Florian Weimer
  2019-04-01 21:17  0%                         ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Florian Weimer @ 2019-03-29 22:35 UTC (permalink / raw)


* Randy Brukardt:

>>"Florian Weimer" <fw@deneb.enyo.de> wrote in message 
>>news:87sgv5k1j5.fsf@mid.deneb.enyo.de...
>>* Randy Brukardt:
>>
>>> But a better question is whether the Rust borrow checker allows
>>> building proper ADTs for most data structures.
>>
>> The Rust standard library uses unsafe extensively in the
>> implementation of containers.  I'm not sure if this is a problem.
>> Most languages have this property (that the standard library cannot be
>> implemented in the language itself).
>>
>> For container libraries, the only widely-used counter-example (of
>> which I'm aware) is pre-generic Java.
>
> You're saying Ada isn't widely used? And I thought the STL was implemented 
> in C++.

The GNAT implementation doesn't seem particularly memory-safe to me,
looking at Ada.Containers.Bounded_Ordered_Maps (which picked more or
less at random).


^ permalink raw reply	[relevance 7%]

* Re: Intervention needed?
  @ 2019-03-22  2:30  7%                             ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2019-03-22  2:30 UTC (permalink / raw)


"Jere" <jhb.chat@gmail.com> wrote in message 
news:f610da94-1309-4cb6-8c7b-47f3099381e5@googlegroups.com...
...
> I don't know if you saw my earlier question to you (from a while back in
> this email chain), but do you know if Tucker was looking at the recent
> upgrades to the ownership scheme?  Some of them may (or may not) be useful
> for Ada (if that gets implemented).  In particular, in the old ownership
> scheme, if you needed to use a throwaway variable to capture a return 
> result
> in Rust, you couldn't reborrow again until that throwaway variable went
> out of scope.  In the updated system, they are able to tell it is 
> throwaway
> and allow for the ownership transfer.  I was thinking about this for
> Ada particularly since we are required to capture function returns into
> some sort of variable.

I can't speak to what Tucker did or did not read about, but the latest 
approach uses a mix of compile-time and runtime checks to ensure that the 
owner really is the owner of the designated object. He has a number of 
examples using discriminants to carry the owner along at runtime (this is 
roughly how cursors already work in the Ada.Containers anyway, so it isn't a 
big change for them).

I'm pretty sure the SPARK people are only interested in static checks, for 
the obvious reason that they are only interested in static checks in 
general.

                      Randy.



^ permalink raw reply	[relevance 7%]

* Re: Intervention needed?
  @ 2019-03-22  2:26  9%                               ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2019-03-22  2:26 UTC (permalink / raw)


"Jere" <jhb.chat@gmail.com> wrote in message 
news:5dbd0a83-2d28-4c39-a973-2f0365d93846@googlegroups.com...
> On Tuesday, March 19, 2019 at 6:26:51 PM UTC-4, Paul Rubin wrote:
>> "Randy Brukardt" writes:
>> > Rust...  You can't build a cursor that way (nor a doubly-linked
>> > list). Perhaps the Rust people have gone beyond simple borrow
>> > semantics -- I don't know.
>>
>> I did a little web searching and it does seem to me that as of a year or
>> so ago, the way to make doubly linked lists in Rust was to call some
>> kind of unchecked library.  I'd like to know how it's done in ATS, and
>> I might ask on a Rust chat if it's still like that in Rust.
>>
>> I think it might be a serious issue for Rust, since one of Rust's
>> driving applications was web browsers.  Those build DOM trees where
>> nodes point to both their children and their parent, so the tree is full
>> of cycles.
>
> If you need either doubly linked lists or maps in Rust, you use the
> ones provided by the standard library (std::collections::list, for
> example, is the doubly linked list).  It's not unchecked at all.

But then why do you need pointers at all? The only cases where they are 
interesting is when they are heavily aliased; otherwise, you're better off 
using containers from the standard library or even your own types (as in Ada 
discriminated records). And it's that sort of aliasing that Rust is aiming 
to eliminate.

I'm sure that there is *some* example (there always is some example :-), but 
hardly enough to make something a programming language feature.

What I'm concerned about primarily is the ability to build ADTs that work 
like the Ada containers. If you have to do a bunch of unchecked stuff to do 
that, then they aren't safe at all. And one can't expect the 
implementation's library to provide *everything* for you.

                                                      Randy.





^ permalink raw reply	[relevance 9%]

* Re: Intervention needed?
  @ 2019-03-22  2:00  8%                                 ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2019-03-22  2:00 UTC (permalink / raw)


"Jere" <jhb.chat@gmail.com> wrote in message 
news:94a74b21-9c35-4f90-90f8-6262cde49e20@googlegroups.com...
...
> You would think that a container of limited types would be very 
> restrictive,
> but with the advent of Implicit_Dereference and reference types, there
> is definitely some meat there.  I would say maps and lists are the two
> areas I find the most need.

A container of a limited type would be very restrictive. ;-)

Several of us (including me) have tried to imagine how a container of 
limited objects would work, but it just doesn't make much sense. The primary 
problem is that one cannot control the lifetime of objects in a container, 
which includes the problem that one can't control the initialization of 
objects in a container. Whereas for non-limited objects, one just replaces 
them with the right data, you can't do that for a limited object. And since 
the initialization needs are type-dependent, there's no good way to deal 
with it in a type-safe manner. (A constructor with an unknown set of 
parameters isn't going to be type-safe, and with any particular set of 
parameters is too limiting.

Note that the same sort of thing applies to controlled objects -- it's not 
recommended to put controlled objects into any of the Ada.Containers with 
the possible exception of the undefinite containers. That's because the 
creation and destruction of objects is up to the container, not under any 
sort of program control. (Deleting an element does not necessarily delete 
the object.)

                             Randy.



^ permalink raw reply	[relevance 8%]

* Re: Intervention needed?
  @ 2019-03-19 22:21  9%                       ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2019-03-19 22:21 UTC (permalink / raw)


"Optikos" <optikos@verizon.net> wrote in message 
news:aa13d9dd-69e9-48ac-99d0-3fabef216781@googlegroups.com...
...
> A container could have (as a required fundamental axiom) a singly-linked
>list of spirits of all cursors ever created that reference it.

Matt suggested such an implementation when the containers were designed. But 
only for deep testing, because...

>As each cursor's life ends, that dying cursor directly knows O(1) where its
>spirit is within that linked list, and then removes its dying spirit too.

This means that each cursor has to be controlled (explicitly or with 
something that is effectively the same), and that means that cursor 
operations are going to be much more expensive. Particularly operations that 
return cursors from functions. (Those are probably 10x slower.) And since 
iterations are built on a bunch of such functions, it too would be much 
slower.

I don't think anyone would accept the Ada containers if they are 
intentionally that slow by design. (The place where that was true in Ada 
2012 has spawned a lot of revision in Ada 2020, it would be madness to put 
it back somewhere else.)

                                                 Randy.


^ permalink raw reply	[relevance 9%]

* Re: How to access Vector.Index_Type?
  2019-03-17 20:43  9% How to access Vector.Index_Type? jakub.dabek
                   ` (2 preceding siblings ...)
  2019-03-18  5:27  0% ` J-P. Rosen
@ 2019-03-18 19:35  0% ` Jeffrey R. Carter
  3 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2019-03-18 19:35 UTC (permalink / raw)


On 3/17/19 9:43 PM, jakub.dabek@gmail.com wrote:
> I have the following program
> 
>      with Ada.Containers.Vectors;
> 
>      procedure Test is
>          package MyVec is new Ada.Containers.Vectors(Natural, Natural);
>          Var : MyVec.Index_Type;
>      begin
>          null;
>      end;
> 
> I get the following error:
> "Index_Type" is not a visible entity of "MyVec"
> 
> How can I access the index type (`Element_Type` gives the same error message), without just writing `Natural`?

This is refreshing. Usually people complain that Ada makes them type too much. 
It's unusual to see someone complain that Ada makes them type less than they want.

If you are dealing with pkg Myvec, Ada presumes that you will look at the 
instantiation and see that it says

Index_Type => Natural

and use Natural when you want an index.

-- 
Jeff Carter
"What I wouldn't give for a large sock with horse manure in it."
Annie Hall
42

^ permalink raw reply	[relevance 0%]

* Re: How to access Vector.Index_Type?
  2019-03-18  5:27  0% ` J-P. Rosen
@ 2019-03-18  8:31  0%   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2019-03-18  8:31 UTC (permalink / raw)


On 2019-03-18 06:27, J-P. Rosen wrote:
> Le 17/03/2019 à 21:43, jakub.dabek@gmail.com a écrit :
>> I have the following program
>>
>>      with Ada.Containers.Vectors;
>>
>>      procedure Test is
>>          package MyVec is new Ada.Containers.Vectors(Natural, Natural);
>>          Var : MyVec.Index_Type;
>>      begin
>>          null;
>>      end;
>>
>> I get the following error:
>> "Index_Type" is not a visible entity of "MyVec"
>>
>> How can I access the index type (`Element_Type` gives the same error 
>> message), without just writing `Natural`?
>>
> Why would you do that? If you instantiate Vectors on Natural, it's 
> because you want a vector of Natural! Therefore it makes sense to use 
> Natural. The name "Index_Type" is a formal, not an actual type, it's 
> just the package's business.

surely for maintenance and code quality reasons. In the example 
everything is clear, but in other (more realistic) scenarios the package 
MyVec might come from other packages only to be used in Test. The 
procedure Test must then use the least possible assumption about the 
index type and be ready to the cases when the type would change, e.g. 
become an enumeration type.

P.S. It is a longstanding issue with visibility of formal generic 
parameters. Anybody who used generics was hit by it more than once. I 
don't know if anything was attempted recently to fix that. A life-hack 
(that does not apply to existing packages) was/is to rename or subtype 
each formal parameter of the generic:

    generic
       type T is <>;
       with package Bar ...
    package Foo is
       subtype The_T is T;
       package The_Bar renames Bar;

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

^ permalink raw reply	[relevance 0%]

* Re: How to access Vector.Index_Type?
  2019-03-17 20:43  9% How to access Vector.Index_Type? jakub.dabek
  2019-03-17 21:25  0% ` Simon Wright
  2019-03-18  4:17  7% ` gautier_niouzes
@ 2019-03-18  5:27  0% ` J-P. Rosen
  2019-03-18  8:31  0%   ` Dmitry A. Kazakov
  2019-03-18 19:35  0% ` Jeffrey R. Carter
  3 siblings, 1 reply; 200+ results
From: J-P. Rosen @ 2019-03-18  5:27 UTC (permalink / raw)


Le 17/03/2019 à 21:43, jakub.dabek@gmail.com a écrit :
> I have the following program
> 
>      with Ada.Containers.Vectors;
> 
>      procedure Test is
>          package MyVec is new Ada.Containers.Vectors(Natural, Natural);
>          Var : MyVec.Index_Type;
>      begin
>          null;
>      end;
> 
> I get the following error:
> "Index_Type" is not a visible entity of "MyVec"
> 
> How can I access the index type (`Element_Type` gives the same error message), without just writing `Natural`?
> 
Why would you do that? If you instantiate Vectors on Natural, it's 
because you want a vector of Natural! Therefore it makes sense to use 
Natural. The name "Index_Type" is a formal, not an actual type, it's 
just the package's business.

-- 
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	[relevance 0%]

* Re: How to access Vector.Index_Type?
  2019-03-17 20:43  9% How to access Vector.Index_Type? jakub.dabek
  2019-03-17 21:25  0% ` Simon Wright
@ 2019-03-18  4:17  7% ` gautier_niouzes
  2019-03-18  5:27  0% ` J-P. Rosen
  2019-03-18 19:35  0% ` Jeffrey R. Carter
  3 siblings, 0 replies; 200+ results
From: gautier_niouzes @ 2019-03-18  4:17 UTC (permalink / raw)


>         package MyVec is new Ada.Containers.Vectors(Natural, Natural);
>         Var : MyVec.Index_Type;

Try:
  subtype My_Index is Natural;
  subtype My_Element is Natural;
  package MyVec is new Ada.Containers.Vectors(My_Index, My_Element);
  Var : My_Index; 


^ permalink raw reply	[relevance 7%]

* Re: How to access Vector.Index_Type?
  2019-03-17 20:43  9% How to access Vector.Index_Type? jakub.dabek
@ 2019-03-17 21:25  0% ` Simon Wright
  2019-03-18  4:17  7% ` gautier_niouzes
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 200+ results
From: Simon Wright @ 2019-03-17 21:25 UTC (permalink / raw)


jakub.dabek@gmail.com writes:

> I have the following program
>
>     with Ada.Containers.Vectors;
>
>     procedure Test is
>         package MyVec is new Ada.Containers.Vectors(Natural, Natural);
>         Var : MyVec.Index_Type;
>     begin
>         null;
>     end;
>
> I get the following error:
> "Index_Type" is not a visible entity of "MyVec"
>
> How can I access the index type (`Element_Type` gives the same error
> message), without just writing `Natural`?

You could use

   subtype My_Index_Type is MyVec.Extended_Index
     range MyVec.Extended_Index'First + 1 .. MyVec.Extended_Index'Last;


^ permalink raw reply	[relevance 0%]

* How to access Vector.Index_Type?
@ 2019-03-17 20:43  9% jakub.dabek
  2019-03-17 21:25  0% ` Simon Wright
                   ` (3 more replies)
  0 siblings, 4 replies; 200+ results
From: jakub.dabek @ 2019-03-17 20:43 UTC (permalink / raw)


I have the following program 

    with Ada.Containers.Vectors;

    procedure Test is
        package MyVec is new Ada.Containers.Vectors(Natural, Natural);
        Var : MyVec.Index_Type;
    begin
        null;
    end;

I get the following error:  
"Index_Type" is not a visible entity of "MyVec"  

How can I access the index type (`Element_Type` gives the same error message), without just writing `Natural`?

^ permalink raw reply	[relevance 9%]

* Re: "Equality operator appears too late"
  2018-11-10 10:36 10% "Equality operator appears too late" JLotty
  2018-11-10 13:34  7% ` joakimds
@ 2019-03-12 11:47  0% ` Simon Wright
  1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2019-03-12 11:47 UTC (permalink / raw)


On Saturday, 10 November 2018 10:36:31 UTC, JLotty  wrote:

>         27:7 equality operator appears too late
>         27:7 instantiation error at a-cuprqu.ads:76
> 
> The error is occurring when the builder tries to elaborate the Ada.Containers.Unbounded_Priority_Queues 
> package, where and "=" operator is defined on line 76.

Did this error get reported to AdaCore?

I spotted it in the latest AUJ, and have worked out a patch (rename the 
"=" function to Eq & replace calls to it). Not sure whether the original 
equality operator was in fact too late, which would be a compiler problem 
if it wasn’t.

^ permalink raw reply	[relevance 0%]

* Re: Intervention needed?
  2019-03-08 17:31  7% ` gautier_niouzes
@ 2019-03-11 14:31  0%   ` antispam
  0 siblings, 0 replies; 200+ results
From: antispam @ 2019-03-11 14:31 UTC (permalink / raw)


gautier_niouzes@hotmail.com wrote:
> You could mention that you can can have dynamically sized variables or objects on the stack, thanks to unconstrained types. No pointers at all, no heap allocation.
> 
> For complex cases like trees, linked lists, etc. you can use the Ada.Containers which have deterministic (then predictable) garbage collection via finalization.

Major issue with dynamically sized variables is running out of
memory.  How do you solve this?  Note that in modern environment
stacks tend to be tiny compared to heap, so this problem is
much more serious when using stack allocation.

-- 
                              Waldek Hebisch


^ permalink raw reply	[relevance 0%]

* Re: Intervention needed?
  @ 2019-03-08 17:31  7% ` gautier_niouzes
  2019-03-11 14:31  0%   ` antispam
    1 sibling, 1 reply; 200+ results
From: gautier_niouzes @ 2019-03-08 17:31 UTC (permalink / raw)


You could mention that you can can have dynamically sized variables or objects on the stack, thanks to unconstrained types. No pointers at all, no heap allocation.

For complex cases like trees, linked lists, etc. you can use the Ada.Containers which have deterministic (then predictable) garbage collection via finalization.

^ permalink raw reply	[relevance 7%]

* Re: warehouse automation in ADA? robots?
  @ 2019-02-27 12:30  6%     ` Björn Lundin
  0 siblings, 0 replies; 200+ results
From: Björn Lundin @ 2019-02-27 12:30 UTC (permalink / raw)


On 2019-02-27 11:28, Jesper Quorning wrote:
> On Tuesday, February 26, 2019 at 10:14:19 AM UTC+1, björn lundin wrote:
> 
>> WCS - Warehouse Control System
>>        The system plan and carry out transports in automatic equipment.
>>        Usally the WMS manages the forklift drivers
>>
>>        Sattmate and vendor specific ones (All
>>        companies above has one but Sattmate is the only (or one of the
>>        few) non-vendor Control system that I know of (in Europe)
> 
> I have heard about a system from the swedish compagny ConSafe using Ada extensively for WCS. Free from my memory they are upgrading from Ada 83 to Ada 2000-something in the Copenhagen area..
> 
> Maybe somone reading CLA can confirm or reject this..?
> 
> 
>         Jesper.
> 

I can. I am Chief Architect for Automation at Consafe Logistics SE.
The product you refer to is the one I referred to as sattmate above.
I am the chief developer/maintainer of it as well

It is a stand-alone WCS system, entirely in Ada. Was in Ada 83,
But during the years, som OO has snuck in and some 2012 features
like contracts in some low level packages (by Jacob Sparre Andersen)
and inheritance of Ada.Finalization ,
use of Ada.Directories
and Ada.Containers.*
and for x of container loops (by me)

There was also a WMS product in Ada, with which the WCS is related to
That one is pronounced End-of-Life 2021
I was one of the developers in that product too.

But we were never upgrading from Ada83 to Ada whatever as such.
When we found new features in the language, we introduced them.
Like the Ada.Directories package. Meant that I could throw out
different home-brewed directory handling on Windows and AIX/Linux and
replace it with the standard package.

The backwards compatibility of the language is great, so we were/are
never afraid of using a new compiler on old code. Had been done lots of
times, and never failed.

And yes, for the WMS, we have many customers in the Copenhagen area.
Actually, I think you'd have a hard time to find a grocery store that is
not handled by us, in Denmark. (I think there are some, but the main
ones runs Ada)

-- 
--
Björn

^ permalink raw reply	[relevance 6%]

* Re: class wide iterable (and indexable)
  2019-01-02 15:48  4% class wide iterable (and indexable) George Shapovalov
  2019-01-02 17:39  6% ` Simon Wright
@ 2019-01-26 22:11  4% ` George Shapovalov
  1 sibling, 0 replies; 200+ results
From: George Shapovalov @ 2019-01-26 22:11 UTC (permalink / raw)


Original poster here.
I think I did it again - that is broke gnat again. 

But first a small update: I have cleaned up and systematized the original code somewhat and added the description. Plus I added the complete "demo" code of the basic mix-in situations. No proper description yet though. The general idea is to create a small depository of common composition situations, to have some base tested code that can be expanded upon.. Two sample compositions are implemented in the code already: the basic mix-ins and the "list interface" over which Ada.Containers.Vectors.Vector can be directly overlayed (among other implementations).
The link to the project is here:
https://github.com/gerr135/ada_composition
(renamed from original ada_gems to avoid name clash with existing Ada Gems by AdaCore).

In trying to expand on that last example - the indexable/iterable and overlayable by existing type interface, I have stumbled upon a rather weird behavior of compiled code. The expansion deals with trying to tie a type hierarchy to the hierarchy of list implementations - not to have a single generic type at the top and children units using the same. Instead this code has a generic interface at the top, and children take specific types implementing interface at the top. This works fine (with minimal code changes in the "library" itself from the previous case) for the basic composition types (record encapsulating wither array of ACV.Vector). But when I try to pass ACV.Vector overlais directly over interface as a generic parameter, it seems the compiler gets confused. While passing the constructed Vector into the List object it raises run-time exception:
raised PROGRAM_ERROR : adjust/finalize raised STORAGE_ERROR: System.Memory.Alloc: heap exhausted

which is rather weird in itself. What's more, a simple whitespace change - splitting the line of code directly above into two (inserting line break between two trivial TEXT_IO ops that are in the same line in the code) changes that error into:
raised PROGRAM_ERROR : adjust/finalize raised STORAGE_ERROR: stack overflow or erroneous memory access

The line of code in question is this:
ld(i) := Base_Interface'Class(set_idx_vector(i));

the setter runs fine (and identical setter for a differently composed version of the base type completes fine *and* allows the constructed object to be passed), but attempt to assign the constructed object to the List container blows up with that STORAGE_ERROR. Please note: only the last variant is affected, that is List composition directly overlaying ACV.Vector over List_Interface, *but not* a more common encapsulation having ACV.Vector a record entry.

Unfortunately. as before, I cannot post just a line or two of code that would reproduce the entire situation. Providing indexing and iteration for the entire type hierarchy takes some code. Please see this specific link for the appropriate part:
https://github.com/gerr135/ada_composition/tree/master/list_combo

This *is* the minimal code that reproduces the situation as far as I can tell..

I cannot see why this specific variant would be "wrong" in some way - the overal interface is the same for all 3 variants. Plus that weird behavior (sensitivity to whitespace) makes me suspect some problem with gnat here. But maybe I overlooked something.
Any ideas are appreciated. 
Thank you!


^ permalink raw reply	[relevance 4%]

* Why forbid local generic instantiations?
@ 2019-01-25  9:43  5% joakimds
  0 siblings, 0 replies; 200+ results
From: joakimds @ 2019-01-25  9:43 UTC (permalink / raw)


Hi!

Consider the following code:

procedure Main is
   package Integer_Vectors is new Ada.Containers.Vectors (Positive, Integer);
begin
   null;
end Main;

It has a generic package instantiation local to the subprogram Main and not defined on package level. Both in AdaControl and GNATCheck there are rules to forbid local generic instantiations.

For example GNATCheck:
23.7.25 Generics_In_Subprograms

 Flag each declaration of a generic unit in a subprogram. Generic declarations in the bodies of generic subprograms are also flagged. A generic unit nested in another generic unit is not flagged. If a generic unit is declared in a local package that is declared in a subprogram body, the generic unit is flagged. 

This rule has no parameters.




Using AdaControl one can use the following rule to detect insantiations of generic packages/subprograms:
5.10 Declarations

This rule controls usage of various kinds of declarations, possibly only those occurring at specified locations. 
...



Why is it considered bad practise to use local generic instantiations? Within the C++ Community, limiting the use of templates doesn't seem an issue. On the contrary, going all in with template metaprogramming is the norm.

Does local generic instantiations have a performance penalty? Is it something that may be error-prone? Limit cross-compiler compatibility? Why does the rule exist to ban local instantiations? I've been googling/searching the web for an answer to this question but have not found an explanation. Does anybody know?

Best regards,
Joakim


^ permalink raw reply	[relevance 5%]

* Re: class wide iterable (and indexable)
  @ 2019-01-06  9:34  6%                 ` George Shapovalov
  0 siblings, 0 replies; 200+ results
From: George Shapovalov @ 2019-01-06  9:34 UTC (permalink / raw)


> > You can using a Mixin Generic along with the interface.  Consider the
> > following example:
> >   <SNIPPED>
> 
> And if you don't like the Mixin method, you can do something a bit closer to
> composition and Rust's model 
Thank you!
Yes, this does the job done (and I believe the 1st one was what Dmitry already have shown above), achieving the effect of in-mixing overridable methods. However allowing interfaces to have non0bull or abstract primitives (obviously referencing onyl existing entities, just like class-wide methods do already anyway) would have been much less cumbersome and much more elegant and readable to begin with..

But this was just a sidenote to that discussion. My original intention was to attempt to move the existing type (that would serve as a top of type hierarchy normally) to the side of a new type tree - which is not that "topologically different" from the mix-in equiliristic, just a bit different way to glue things together. The complicating circumstance in that specific case (which prompted my original post) was to provide indexing/iteration to the entire type tree and then glue Ada.Containers.Vectors right over it, which finally succeeded after more digging through aspects and Ada standard library internals.

Tanks to everybody for informative comments!

^ permalink raw reply	[relevance 6%]

* Re: class wide iterable (and indexable)
  @ 2019-01-05 18:17  5%               ` George Shapovalov
  0 siblings, 0 replies; 200+ results
From: George Shapovalov @ 2019-01-05 18:17 UTC (permalink / raw)


On Saturday, January 5, 2019 at 11:07:57 AM UTC+1, Dmitry A. Kazakov wrote:
> That is because compilers are no longer large software, not even 
> medium-size (:-)). My current project takes a half of week to recompile 
> from scratch.
Sorry to break up this "high opinions" discussion, it is as usual interesting to see varying points of view. Incidentally, having done a few long-standing projects and having maintained Ada in Gentoo Linux (which, in Gentoo's case, implies digging deep into gcc toolchain inner workings), I am of similar to Drmitry's opinion on this point (even though gcc, while bigger than Janus Ada, is still is nowhere near that kind of scale of course).

Nonetheless, back to the original point.
A small update on the original issue:

I have finally had some time to wrap my head around this issue a bit more and I have completed the implementation. Now it builds and tests fine for all cases - specific types and class-wide vars alike. The issue was not just some simple omission. In fact there was not just a single issue - complete implementation required implementing parallel type hierarchies (although with minimum of duplicated code - only for illustration purpose in this case; could be tied up even more, see the comments in the code if anybody is interested by any chance). I essentially ended up reimplementing Ada "standard library", of course in a very simplistic variant, demo-like.  Still, I managed to glue Ada.Containers.Vectors.Vector right over the List_Interface, thus exposing ACV.Vector's primitives directly without extra glue needed. The corresponding code is in the master of:
https://github.com/gerr135/ada_gems/tree/master/list_iface

While digging, I tried alternatives, one of which "hides" the ACV.Vector inside a record - a more classical approach, easier to comprehend (even though the code is mostly the same, less than 10 lines of difference). This code is in "in_rec" branch:
https://github.com/gerr135/ada_gems/tree/in_rec/list_iface


Finally, at some point while testing different things I managed to break gnat, causing it to spill out that gnat Bug message. Relevant code and error message are in yet another branch, here:
https://github.com/gerr135/ada_gems/tree/gnat_bug_01/list_iface

the bug message text is in the "bug_info.txt" file at the top of the list_iface folder..

Is this something already well known or should I report this bug to AdaCore?


^ permalink raw reply	[relevance 5%]

* Re: class wide iterable (and indexable)
  2019-01-04  4:32  0%       ` Shark8
@ 2019-01-05  9:03  0%         ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2019-01-05  9:03 UTC (permalink / raw)


"Shark8" <onewingedshark@gmail.com> wrote in message 
news:95f6a9b0-adc6-4044-8ff8-f0820612aeea@googlegroups.com...
> On Thursday, January 3, 2019 at 1:52:50 AM UTC-7, Simon Wright wrote:
>>
>>
>> The Ada 95 Booch Components[4] follow this model. One reason they
>> weren't taken as a model for Ada.Containers was that the model requires
>> multiple levels of generic instantiation of child packages: for example,
>> to make an unbounded map from Unbounded_String to Unbounded_String
>> requires
>>
>>    with Ada.Strings.Unbounded;
>>    with BC.Containers.Maps.Unbounded;
>>    with BC.Support.Standard_Storage;
>>
>>    package Configuration_Demo_Support is
>>
>>       package Abstract_String_Containers is new BC.Containers
>>         (Item => Ada.Strings.Unbounded.Unbounded_String,
>>          "=" => Ada.Strings.Unbounded."=");
>>
>>       package Abstract_String_Maps
>>       is new Abstract_String_Containers.Maps
>>         (Key => Ada.Strings.Unbounded.Unbounded_String,
>>          "=" => Ada.Strings.Unbounded."=");
> True; but the Automatic Instantiation AI would relieve a lot of the hassle 
> here --  
> http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0268-1.txt?rev=1.2

The AI you refer to is only about formal packages, while the above doesn't 
have any formal packages so I fail to see how it would help.

A more general automatic instantiation mechanism was also proposed in 
AI12-0215-1. But that one is a dead-body issue for me (at least as 
proposed). Ada gives specific places where every declaration occurs 
(statically) and is elaborated (dynamically). AI12-0215-1 throws that 
property completely away, harming analyzability, readability, and 
understandability -- it would be much like saying that there's no neeed to 
declare objects before using them because the compiler can figure out what 
was intended. Bah humbug. :-)

                            Randy.


^ permalink raw reply	[relevance 0%]

* Re: class wide iterable (and indexable)
  2019-01-03  8:52 11%     ` Simon Wright
  2019-01-03  9:30  6%       ` George Shapovalov
@ 2019-01-04  4:32  0%       ` Shark8
  2019-01-05  9:03  0%         ` Randy Brukardt
  1 sibling, 1 reply; 200+ results
From: Shark8 @ 2019-01-04  4:32 UTC (permalink / raw)


On Thursday, January 3, 2019 at 1:52:50 AM UTC-7, Simon Wright wrote:
> 
> 
> The Ada 95 Booch Components[4] follow this model. One reason they
> weren't taken as a model for Ada.Containers was that the model requires
> multiple levels of generic instantiation of child packages: for example,
> to make an unbounded map from Unbounded_String to Unbounded_String
> requires
> 
>    with Ada.Strings.Unbounded;
>    with BC.Containers.Maps.Unbounded;
>    with BC.Support.Standard_Storage;
> 
>    package Configuration_Demo_Support is
> 
>       package Abstract_String_Containers is new BC.Containers
>         (Item => Ada.Strings.Unbounded.Unbounded_String,
>          "=" => Ada.Strings.Unbounded."=");
> 
>       package Abstract_String_Maps
>       is new Abstract_String_Containers.Maps
>         (Key => Ada.Strings.Unbounded.Unbounded_String,
>          "=" => Ada.Strings.Unbounded."=");
True; but the Automatic Instantiation AI would relieve a lot of the hassle here -- http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0268-1.txt?rev=1.2  

^ permalink raw reply	[relevance 0%]

* Re: class wide iterable (and indexable)
  2019-01-03 22:56  0%     ` Randy Brukardt
@ 2019-01-04  0:00  4%       ` George Shapovalov
    0 siblings, 1 reply; 200+ results
From: George Shapovalov @ 2019-01-04  0:00 UTC (permalink / raw)


> Vectors support both indexing by an integer and reference via a cursor. 
> Usually, the List container is a better example for cursor operations 
> because it doesn't have the confusion of (direct) indexing involved.
Ah, right, that Ada gem I initially read was indeed operating on linked lists. This is why it only implemented one method. But I needed the indexing too in my case, which is attached via different aspects. So it all seemed to correspond so far and even work, as long as I did not try to do an "of-loop" over class-wide var (derived types worked fine).


> Because that would substantially harm ease-of-use. You'd have to write 
> multiple instantiations to create any container. It's annoying enough (to 
> some, at least) to have to write one.
Well, I rather consider an extra line of (typically elementary) code a small price for versatility, but then apparently opinions vary a lot on this one :). 
But the next point is more essential:

 
> Besides, interfaces are (nearly) useless (and especially so for this sort of 
> usage, where some part has to be generic). They add a lot of runtime 
> overhead that doesn't actually get used in real programs.
Really? I did not consider this. I thought there would be no extra overhead, as the compiler should be able to select appropriate constructs as needed and optimize away with higher -OX. But indeed, in case of generics it would likely produce extra code blobs.. Oh, well, looks like I may be better off with a more simplistic design, using getters/setters and iterating over the provided index type (which is needed there anyway). Looks like that would be more efficient with generics, even though less elegant. Those extra get/set qualifiers instead of direct indexed access look a bit annoying :). But this is really a minor issue. And at least I learned a thing or two about inner gnat workings on the way :).

> Perhaps if Ada allowed multiple controlling parameters of different tagged 
> types, then there might be more use.
Funny that you mention this one. That was my thought exactly at one (completely unrelated) point - that unlike most other languages, Ada has the syntax that could naturally allow multiple controlling parameters, and that could be a really powerful type composition feature.. A pity this was not done so, that would be a fun feature. But then I do realize that it takes a special kind of thought organization (more pure math than typical procedural idiom most programmers follow) for the developer to feel comfortable with such a feature. With most other common languages not having even a provision to formulate such a structure, most developers would be at a loss to comprehend what is even proposed in the standard I am afraid (at least from what I could observe). So I can see why this was not seriously considered. Plus that would give a huge potential for abuse - just think of all the possible combinations multiplying complexity, having to turn simple dispatch tables into multidimensional (and very sparse) arrays..

Btw, I'd rather say that this, and not the (not so evident) observation of extra overhead is the main reason for:
> For example, we 
> did do what you suggest for the queue containers. Irrelevant thought: that's 
> probably why I have yet to hear of anyone actually using one of them. :-) 
That, and (more essentially) that the standard Ada.Containers are sufficient for most situations, as you point out elsewhere.


> But with the existing Ada rules, 
> interfaces can only be useful if the profiles are fixed (non-generic) and 
> are still reusable -- that doesn't happen that often.
Why? 
Besides the optimization issues, which are invisible to end user and often are not so critical, I fail to see how generics would affect logical structure of the program in this case. Besides linking various type hierarchies together, interfaces are good for containing common code that does not care about specific data storage details. How generics complicate the issue? (at the level of program logic, not underlying code - most apps away from critical domains do not care about 2x size or loss of 10% time efficiency away from critical loops, if that allows to reuse well tested code). In fact it seems to me that generics fit very well with such development model..


^ permalink raw reply	[relevance 4%]

* Re: class wide iterable (and indexable)
  2019-01-02 18:11  9%   ` George Shapovalov
  2019-01-03  8:52 11%     ` Simon Wright
@ 2019-01-03 22:56  0%     ` Randy Brukardt
  2019-01-04  0:00  4%       ` George Shapovalov
  1 sibling, 1 reply; 200+ results
From: Randy Brukardt @ 2019-01-03 22:56 UTC (permalink / raw)


"George Shapovalov" <gshapovalov@gmail.com> wrote in message 
news:2a6929c5-72fa-4d84-953a-44ea4597ab38@googlegroups.com...
...
>I did see in the Ada.Containers.Vectors code two versions defined, however 
>I was not
>clear on why, especially since both the Ada Gem 10x (I forgot now exact 
>number) and
>Ada Rationale for 2012 seem to only provide one, with a Cursor.

Vectors support both indexing by an integer and reference via a cursor. 
Usually, the List container is a better example for cursor operations 
because it doesn't have the confusion of (direct) indexing involved.

...
>On a related note, I was rather surprised that the related types in 
>Ada.Containers do not
>form such a hierarchy. Say both Ada.Containers.Vectors and 
>Indefinite_Vectors (and
>especially now with addition of Bounded_Vectors too) all could derive from 
>a common
>ancestor that could be used to implement common functionality and let end 
>user chose
>the desired data storage model..

Because that would substantially harm ease-of-use. You'd have to write 
multiple instantiations to create any container. It's annoying enough (to 
some, at least) to have to write one.

Besides, interfaces are (nearly) useless (and especially so for this sort of 
usage, where some part has to be generic). They add a lot of runtime 
overhead that doesn't actually get used in real programs. For example, we 
did do what you suggest for the queue containers. Irrelevant thought: that's 
probably why I have yet to hear of anyone actually using one of them. :-) 
Back to the point: there's virtually no circumstance where you'd use more 
than one type of queue with any specific data type, so the generality buys 
essentially nothing. (The only real use is in generic units, but those could 
have been handled with formal packages just as well.) So you're paying a 
substantial price in code size and time, but no real gain.

Perhaps if Ada allowed multiple controlling parameters of different tagged 
types, then there might be more use. But with the existing Ada rules, 
interfaces can only be useful if the profiles are fixed (non-generic) and 
are still reusable -- that doesn't happen that often.

                               Randy.





^ permalink raw reply	[relevance 0%]

* Re: class wide iterable (and indexable)
  2019-01-03  8:52 11%     ` Simon Wright
@ 2019-01-03  9:30  6%       ` George Shapovalov
  2019-01-04  4:32  0%       ` Shark8
  1 sibling, 0 replies; 200+ results
From: George Shapovalov @ 2019-01-03  9:30 UTC (permalink / raw)


> ARM A.18.2(34.3)ff[1] has both forms.
Ah, thank you for the pointer. Unfortunately ARM is a rather heavy reading, targeted more at language implementation (so, not the first place to look at if there are other sources). But I guess I enter this territory already while trying to reimplement indexing and iteration..

> You might be interested in Emmanuel's 'traits'-based containers, see
> [2], [3].
Thanks, I'll take a look.

> The Ada 95 Booch Components[4] follow this model. One reason they
> weren't taken as a model for Ada.Containers was that the model requires
> multiple levels of generic instantiation of child packages:
Yes, I am very well aware of that :) (and I used Booch components before, this is also why surprise, as Ada.Containers seem to be rather inspired by them).
However here we have the trade-off of an extra few clear lines of code (most commonly one trivial would suffice I suspect) for the capability to do a more "universal" algorithm implementation. I'd say it is well worth it, but apparently this was not the majority opinion..

Thanks again for all the pointers!
George



^ permalink raw reply	[relevance 6%]

* Re: class wide iterable (and indexable)
  2019-01-02 18:11  9%   ` George Shapovalov
@ 2019-01-03  8:52 11%     ` Simon Wright
  2019-01-03  9:30  6%       ` George Shapovalov
  2019-01-04  4:32  0%       ` Shark8
  2019-01-03 22:56  0%     ` Randy Brukardt
  1 sibling, 2 replies; 200+ results
From: Simon Wright @ 2019-01-03  8:52 UTC (permalink / raw)


George Shapovalov <gshapovalov@gmail.com> writes:

> Thanks!
> I'll try adding this and see if I can get around that invalid
> interface conversion.
>
> I did see in the Ada.Containers.Vectors code two versions defined,
> however I was not clear on why, especially since both the Ada Gem 10x
> (I forgot now exact number) and Ada Rationale for 2012 seem to only
> provide one, with a Cursor.

ARM A.18.2(34.3)ff[1] has both forms.

> However, from your response (also my general impression while digging
> through the iterables workings) is that this is not a common way to
> provide such code unification. How then one is supposed to go about
> such feature?

You might be interested in Emmanuel's 'traits'-based containers, see
[2], [3].

> On a related note, I was rather surprised that the related types in
> Ada.Containers do not form such a hierarchy. Say both
> Ada.Containers.Vectors and Indefinite_Vectors (and especially now with
> addition of Bounded_Vectors too) all could derive from a common
> ancestor that could be used to implement common functionality and let
> end user chose the desired data storage model..

The Ada 95 Booch Components[4] follow this model. One reason they
weren't taken as a model for Ada.Containers was that the model requires
multiple levels of generic instantiation of child packages: for example,
to make an unbounded map from Unbounded_String to Unbounded_String
requires

   with Ada.Strings.Unbounded;
   with BC.Containers.Maps.Unbounded;
   with BC.Support.Standard_Storage;

   package Configuration_Demo_Support is

      package Abstract_String_Containers is new BC.Containers
        (Item => Ada.Strings.Unbounded.Unbounded_String,
         "=" => Ada.Strings.Unbounded."=");

      package Abstract_String_Maps
      is new Abstract_String_Containers.Maps
        (Key => Ada.Strings.Unbounded.Unbounded_String,
         "=" => Ada.Strings.Unbounded."=");

      function Hash (S : Ada.Strings.Unbounded.Unbounded_String)
        return Natural;

      package String_Maps
      is new Abstract_String_Maps.Unbounded
        (Hash => Hash,
         Buckets => 43,
         Storage => BC.Support.Standard_Storage.Pool);

   end Configuration_Demo_Support;

[1] http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-A-18-2.html#p34.3
[2] https://blog.adacore.com/traits-based-containers
[3] https://github.com/AdaCore/ada-traits-containers
[4] https://sourceforge.net/projects/booch95/


^ permalink raw reply	[relevance 11%]

* Re: class wide iterable (and indexable)
  2019-01-02 17:39  6% ` Simon Wright
@ 2019-01-02 18:11  9%   ` George Shapovalov
  2019-01-03  8:52 11%     ` Simon Wright
  2019-01-03 22:56  0%     ` Randy Brukardt
  0 siblings, 2 replies; 200+ results
From: George Shapovalov @ 2019-01-02 18:11 UTC (permalink / raw)


Thanks!
I'll try adding this and see if I can get around that invalid interface conversion. 

I did see in the Ada.Containers.Vectors code two versions defined, however I was not clear on why, especially since both the Ada Gem 10x (I forgot now exact number) and Ada Rationale for 2012 seem to only provide one, with a Cursor. Besides, that seemed to work just fine when specific types are declared, only class-wide gave me trouble.. 
Interesting that indexing works fine, no confusion here (but of course it goes through other aspects, and there I had to change the name of the referenced function in derived type, otherwise the compiler was getting confused too - I left a comment in the code to this effect)..

However, from your response (also my general impression while digging through the iterables workings) is that this is not a common way to provide such code unification. How then one is supposed to go about such feature? 

On a related note, I was rather surprised that the related types in Ada.Containers do not form such a hierarchy. Say both Ada.Containers.Vectors and Indefinite_Vectors (and especially now with addition of Bounded_Vectors too) all could derive from a common ancestor that could be used to implement common functionality and let end user chose the desired data storage model..

^ permalink raw reply	[relevance 9%]

* Re: class wide iterable (and indexable)
  2019-01-02 15:48  4% class wide iterable (and indexable) George Shapovalov
@ 2019-01-02 17:39  6% ` Simon Wright
  2019-01-02 18:11  9%   ` George Shapovalov
  2019-01-26 22:11  4% ` George Shapovalov
  1 sibling, 1 reply; 200+ results
From: Simon Wright @ 2019-01-02 17:39 UTC (permalink / raw)


George Shapovalov <gshapovalov@gmail.com> writes:

> I would be thankful for any pointers, as I am at a loss what that
> class-wide for loop is getting confused about. Or why it even expects
> the Index type in the "of" loop?

Compiling (a subsection of) your code with -gnatG, which lists the
generated expanded code in an Ada-like syntax, we get

      C2220b : test_list_iface__pl__cursor := T2232b!(
        test_list_iface__pl__list_iterator_interfaces__reversible_iteratorH!
        (I2224b).all (1)).all (I2224b);
      L_5 : while test_list_iface__pl__has_element (C2220b) loop
         n : test_list_iface__pl__element_type renames
           test_list_iface__pl__list_reference (lc, C2220b);
         ada__text_io__put__4 (n'img);
         C2220b :=
           $test_list_iface__pl__list_iterator_interfaces__next__2 (
           I2224b, C2220b);
      end loop L_5;

which shows that part of the code (correctly) expects an integer, while
another part provides a cursor; so you're right, the compiler is
confused, this is a compiler bug.

However, I think the issue may be that you've only defined one function
List_Reference: if you look at Ada.Containers.Vectors you'll see

   function Reference
     (Container : aliased in out Vector;
      Position  : Cursor) return Reference_Type;
   pragma Inline (Reference);
...
   function Reference
     (Container : aliased in out Vector;
      Index     : Index_Type) return Reference_Type;
   pragma Inline (Reference);

so GNAT's "bug" is that it doesn't understand how to cope with your
error. AdaCore are always interested in improving error messages, but
this error does seem rather out of the ordinary!

I had a quick-and-dirty go at fixing this, & got a build, but ended with

testing List_Interface'Class ..
assignin values .. done;  values: 
Catchpoint 1, CONSTRAINT_ERROR (Ada.Tags.Displace: invalid interface conversion) at 0x00000001000210da in test_list_iface.pld.iterate (container=..., 
    <iterateBIPalloc>=2, <iterateBIPstoragepool>=0x0, 
    <iterateBIPfinalizationmaster>=0x0, <iterateBIPaccess>=0x0)
    at /Users/simon/tmp/cla/ada_gems/list_iface/src/lists-dynamic.adb:46
46	        return List_Iterator_Interfaces.Reversible_Iterator'Class(ACV.Vector(Container).Iterate);
(gdb) l
41	--     end;
42	
43	    overriding
44	    function Iterate (Container : in List) return List_Iterator_Interfaces.Reversible_Iterator'Class is
45	    begin
46	        return List_Iterator_Interfaces.Reversible_Iterator'Class(ACV.Vector(Container).Iterate);
47	    end;
48	
49	end Lists.dynamic;

Hope this helps ...


^ permalink raw reply	[relevance 6%]

* class wide iterable (and indexable)
@ 2019-01-02 15:48  4% George Shapovalov
  2019-01-02 17:39  6% ` Simon Wright
  2019-01-26 22:11  4% ` George Shapovalov
  0 siblings, 2 replies; 200+ results
From: George Shapovalov @ 2019-01-02 15:48 UTC (permalink / raw)


Hello,

I apologize if something like this is a common thing, but search here or on google does not turn up much of directly related info, and I cannot quite understand why the following confuses gnat..

The intention here is to create a top-level interface providing iterable/indexable, well, interface, with specific derived types providing appropriate data handling (say to let user select either dynamic, Ada.Containers.Vectors based, or fixed, based on plain arrays storage). 

See here for working code:
https://github.com/gerr135/ada_gems/tree/master/list_iface

So, I would have 
package Lists is ..
type List_Interface is interface
        with Constant_Indexing => List_Constant_Reference,
            Variable_Indexing => List_Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type;

package Lists.Dynamic is ..
type List is new List_Interface with private ..

package Lists.Fixed is ..
type List is new List_Interface with private..

with all appropriate elements declared as abstract and derived types implementing them - either directly attaching Vector interface or wrapping around base array..

Then common code could be kept in class-wide methods, using the new loop forms, like in:
--
for item of List loop
  do_something(item);
end loop;
as well as direct indexing, i.e. List(i)
--
with specific storage types selected as needed in client procedures. In most optimistic scenario only declarative region would need light changes..

This all works well in fact, as long as I operate on specific types. But as soon as I try to use class-wide variable, the "of" form of the loop seems to confuse the compiler.
Thus, e.g. 

LL : Lists.Dynamic.List;
for l of LL loop .. -- works fine

but
LC : Lists.List_Interface'Class := Lists.Dynamic.To_Vector(5);
for l of LC loop .. -- confuses the compiler

And I just cannot see what's so special about this class-wide here. It all seems to follow exactly the same form (by design it passes all compiler checks up to this point).

Please see here for the code:
https://github.com/gerr135/ada_gems/tree/master/list_iface

the specific error is:
test_list_iface.adb:91:17: expected type "Standard.Integer"
test_list_iface.adb:91:17: found private type "Cursor" defined at lists.ads:32, instance at line 22
(and one more line further down that is clearly derivative)

This is not quite a 5-line example code, but implementing iterable/indexable interfaces with proper inheritance is somewhat beasty (even if its utility is in concise end-point code). I am afraid this is the minimal code that would illustrate the point (cut and reformed from larger project where I was trying such approach. Perhaps I should turn to iterating over some index type, which needs to be provided anyway. Seems to be simpler and as readable, but what is there the new interface for, if not to be tried out? :) ).

I would be thankful for any pointers, as I am at a loss what that class-wide for loop is getting confused about. Or why it even expects the Index type in the "of" loop?

Thank you for any pointers.

George

^ permalink raw reply	[relevance 4%]

* Re: Сreate attributes.
  2018-12-22  5:37  7% Сreate attributes eduardsapotski
@ 2018-12-22 19:13  0% ` Brad Moore
  0 siblings, 0 replies; 200+ results
From: Brad Moore @ 2018-12-22 19:13 UTC (permalink / raw)


On Friday, December 21, 2018 at 10:37:14 PM UTC-7, eduards...@gmail.com wrote:
> Sorry for the stupid question...
> 
> For example. I have type:
> 
>    type Person is record
>       First_Name : Unbounded_String := Null_Unbounded_String;
>       Last_Name : Unbounded_String := Null_Unbounded_String;
>    end record;
> 
> There is a list:
> 
>    package People_Package is new  Ada.Containers.Vectors(Natural, Person);
>    People : People_Package.Vector;
> 
> Next, I want to display this list with headers:
> 
> ----------------------------
> |   NAME    |   SURNAME    |
> ----------------------------
> |   John    |    Smith     |
> |   Ada     |   Lovelace   |
> ...
> ----------------------------
> 
> Can I use attributes to display headers?
> For example something like this:
> 
> People'First_Name_Header
> 
> 
> How can this be implemented?

You could use a class-wide type or a type with discriminants such as;

   type Person_Attribute_Kinds is (Name, Surname);
   
   type Person_Attribute (Attribute_Name : Person_Attribute_Kinds
                          := Person_Attribute_Kinds'First) is
      record
         case Attribute_Name is
            when Name | Surname =>
               Name_String : Unbounded_String := Null_Unbounded_String;
         end case;
      end record;
      
      type Person is
         record
            First_Name : Person_Attribute(Name);
            Last_Name  : Person_Attribute(Surname);
         end record;
      
   X : Person;
begin
   Put_Line ("| " & X.First_Name.Attribute_Name'Image &
              " | " & X.Last_Name.Attribute_Name'Image & " |");


^ permalink raw reply	[relevance 0%]

* Сreate attributes.
@ 2018-12-22  5:37  7% eduardsapotski
  2018-12-22 19:13  0% ` Brad Moore
  0 siblings, 1 reply; 200+ results
From: eduardsapotski @ 2018-12-22  5:37 UTC (permalink / raw)


Sorry for the stupid question...

For example. I have type:

   type Person is record
      First_Name : Unbounded_String := Null_Unbounded_String;
      Last_Name : Unbounded_String := Null_Unbounded_String;
   end record;

There is a list:

   package People_Package is new  Ada.Containers.Vectors(Natural, Person);
   People : People_Package.Vector;

Next, I want to display this list with headers:

----------------------------
|   NAME    |   SURNAME    |
----------------------------
|   John    |    Smith     |
|   Ada     |   Lovelace   |
...
----------------------------

Can I use attributes to display headers?
For example something like this:

People'First_Name_Header


How can this be implemented?

^ permalink raw reply	[relevance 7%]

* Re: Graph database client? eg Neo4j, Dgraph ...
  2018-12-15  0:59  0%   ` Olivier Henley
@ 2018-12-16 18:23  7%     ` Shark8
  2019-08-20 15:13  0%     ` Shark8
  1 sibling, 0 replies; 200+ results
From: Shark8 @ 2018-12-16 18:23 UTC (permalink / raw)


On Friday, December 14, 2018 at 6:00:00 PM UTC-7, Olivier Henley wrote:
> 
> Thx! I communicated with the author to bring this code on github. More to come.

Wait, really!?
I thought I tried a few years back and couldn't get ahold of him... I'd definitely love to be able talk with him about some ideas for an Ada DB system that I have, as well as update Mneson to use the Ada.Containers packages.

This is excellent news, IME.


^ permalink raw reply	[relevance 7%]

* Re: Graph database client? eg Neo4j, Dgraph ...
  2018-12-13 23:15 10% ` Shark8
@ 2018-12-15  0:59  0%   ` Olivier Henley
  2018-12-16 18:23  7%     ` Shark8
  2019-08-20 15:13  0%     ` Shark8
  0 siblings, 2 replies; 200+ results
From: Olivier Henley @ 2018-12-15  0:59 UTC (permalink / raw)


On Thursday, December 13, 2018 at 6:15:08 PM UTC-5, Shark8 wrote:
> On Wednesday, December 12, 2018 at 7:04:15 AM UTC-7, Olivier Henley wrote:
> > Hi to all,
> > 
> > Anyone knows of an initiative at providing a Neo4j() Ada client? Or any other graph db really...
> 
> There is/was an all-Ada graph-DB called Mneson -- Archived here: https://web.archive.org/web/20070625173813/http://www.liacc.up.pt/~maa/mneson/ -- of which I have a copy of two versions. I was trying to translate them so that instead of the containers dependency ["Charles Containers", IIRC] they would use the Ada.Containers.* packages instead.

Thx! I communicated with the author to bring this code on github. More to come.

^ permalink raw reply	[relevance 0%]

* Re: Graph database client? eg Neo4j, Dgraph ...
  @ 2018-12-13 23:15 10% ` Shark8
  2018-12-15  0:59  0%   ` Olivier Henley
  0 siblings, 1 reply; 200+ results
From: Shark8 @ 2018-12-13 23:15 UTC (permalink / raw)


On Wednesday, December 12, 2018 at 7:04:15 AM UTC-7, Olivier Henley wrote:
> Hi to all,
> 
> Anyone knows of an initiative at providing a Neo4j() Ada client? Or any other graph db really...

There is/was an all-Ada graph-DB called Mneson -- Archived here: https://web.archive.org/web/20070625173813/http://www.liacc.up.pt/~maa/mneson/ -- of which I have a copy of two versions. I was trying to translate them so that instead of the containers dependency ["Charles Containers", IIRC] they would use the Ada.Containers.* packages instead.

^ permalink raw reply	[relevance 10%]

* Re: "Equality operator appears too late"
  2018-11-11  6:32  0%   ` Randy Brukardt
@ 2018-11-11 20:05  0%     ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2018-11-11 20:05 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> <joakimds@kth.se> wrote in message 

>>The error is occurring when the builder tries to elaborate the
>>Ada.Containers.Unbounded_Priority_Queues package, where and
>>"=" operator is defined on line 76.
>
> The language-defined specification of that package doesn't contain any
> "=" operator, so the existence of such a thing itself might be the
> bug.

This is in the package Implementation.

The code compiles OK with GCC 6.1.0 but not with GCC >= 7 or GNAT >=
2016.


^ permalink raw reply	[relevance 0%]

* Re: "Equality operator appears too late"
  2018-11-10 13:34  7% ` joakimds
  2018-11-10 14:36  0%   ` JLotty
@ 2018-11-11  6:32  0%   ` Randy Brukardt
  2018-11-11 20:05  0%     ` Simon Wright
  1 sibling, 1 reply; 200+ results
From: Randy Brukardt @ 2018-11-11  6:32 UTC (permalink / raw)


<joakimds@kth.se> wrote in message 
news:499c632b-c551-46fc-9563-86594aaa0001@googlegroups.com...
> I've tried the code with GNAT Community Edition 2018 and got
> the same error message. My spontaneous guess is that this is a
> compiler bug. The work around would be to rewrite the code not
> to instantiate the generic package
> Ada.Containers.Unbounded_Priority_Queues inside a generic
> compilation unit. I hope somebody else in this forum has a better idea
> on what to do.

Use a different compiler? :-) There rarely is a *good* solution when dealing 
with a compiler bug.

>The error is occurring when the builder tries to elaborate the
>Ada.Containers.Unbounded_Priority_Queues package, where and
>"=" operator is defined on line 76.

The language-defined specification of that package doesn't contain any "=" 
operator, so the existence of such a thing itself might be the bug. Note 
that Ada 2012 adopted rules for overriding of "=" for untagged record types 
similar to those for tagged record types (that was to allow composition to 
make sense), and thus some "=" declarations that were legal in previous Ada 
aren't legal anymore. Perhaps a recent GNAT tightened up these rules and 
caught some of their library code.

                                             Randy.




^ permalink raw reply	[relevance 0%]

* Re: "Equality operator appears too late"
  2018-11-10 13:34  7% ` joakimds
@ 2018-11-10 14:36  0%   ` JLotty
  2018-11-11  6:32  0%   ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: JLotty @ 2018-11-10 14:36 UTC (permalink / raw)


On Saturday, November 10, 2018 at 4:34:52 PM UTC+3, joak...@kth.se wrote:
> I've tried the code with GNAT Community Edition 2018 and got the same error message. My spontaneous guess is that this is a compiler bug. The work around would be to rewrite the code not to instantiate the generic package Ada.Containers.Unbounded_Priority_Queues inside a generic compilation unit. I hope somebody else in this forum has a better idea on what to do.
> 
> Best regards,
> Joakim

I should have included that in my original post.  If I remove the generic components and add in type definitions instead, it compiles just fine. 

^ permalink raw reply	[relevance 0%]

* Re: "Equality operator appears too late"
  2018-11-10 10:36 10% "Equality operator appears too late" JLotty
@ 2018-11-10 13:34  7% ` joakimds
  2018-11-10 14:36  0%   ` JLotty
  2018-11-11  6:32  0%   ` Randy Brukardt
  2019-03-12 11:47  0% ` Simon Wright
  1 sibling, 2 replies; 200+ results
From: joakimds @ 2018-11-10 13:34 UTC (permalink / raw)


I've tried the code with GNAT Community Edition 2018 and got the same error message. My spontaneous guess is that this is a compiler bug. The work around would be to rewrite the code not to instantiate the generic package Ada.Containers.Unbounded_Priority_Queues inside a generic compilation unit. I hope somebody else in this forum has a better idea on what to do.

Best regards,
Joakim


^ permalink raw reply	[relevance 7%]

* "Equality operator appears too late"
@ 2018-11-10 10:36 10% JLotty
  2018-11-10 13:34  7% ` joakimds
  2019-03-12 11:47  0% ` Simon Wright
  0 siblings, 2 replies; 200+ results
From: JLotty @ 2018-11-10 10:36 UTC (permalink / raw)


with Ada.Containers.Synchronized_Queue_Interfaces;
with Ada.Containers.Unbounded_Priority_Queues;
procedure Min_Working_Example is

   generic
      type Data_Type is private;
      type Weight_Type is (<>);
      with function "<" (Left, Right : Weight_Type) return Boolean is <>;
   package Min_Data_Structure is
   private
      type Data_Rec is record
         Data   : Data_Type;
         Weight : Weight_Type;
      end record;
      
      function Get_Priority
        (Element : Data_Rec)
      return Weight_Type;

      function Before
        (Left, Right : Weight_Type)
      return Boolean;

      package Queue_Interface is new Ada.Containers.Synchronized_Queue_Interfaces
        (Data_Rec);

      package Edge_Queue is new Ada.Containers.Unbounded_Priority_Queues
        (Queue_Interfaces => Queue_Interface,
         Queue_Priority   => Weight_Type,
         Get_Priority     => Get_Priority,
         Before           => Before);
   end Min_Data_Structure;
   
   package body Min_Data_Structure is
      function Get_Priority
        (Element : Data_Rec)
         return Weight_Type is
        (Element.Weight);

      function Before
        (Left, Right : Weight_Type)
         return Boolean is
        (Left < Right);
   end Min_Data_Structure;
begin
   null;
end Min_Working_Example;

==================================================
When compiling the above, I get the following error:
Builder results
    min_working_example.adb
        27:7 equality operator appears too late
        27:7 instantiation error at a-cuprqu.ads:76

The error is occurring when the builder tries to elaborate the Ada.Containers.Unbounded_Priority_Queues package, where and "=" operator is defined on line 76.

I'm running the following command for build:
gprbuild -q -c -f -gnatc -u -Ptest.gpr min_working_example.adb

using version:
GPRBUILD GPL 2017 (20170515) (x86_64-pc-linux-gnu)
Copyright (C) 2004-2017, AdaCore

I don't know what to do from here.  Any help you can offer would be appreciated.


^ permalink raw reply	[relevance 10%]

* Re: Ada.Containers and concurrent modification exception.
  2018-09-25 22:32 17%             ` Randy Brukardt
@ 2018-09-26  5:01  9%               ` Petter Fryklund
  0 siblings, 0 replies; 200+ results
From: Petter Fryklund @ 2018-09-26  5:01 UTC (permalink / raw)


Just a try to be funny, you wrote:
We're not talking about "iterators", we're talking about cursors. Iterators 
have the tampering check (an iterator being an --->active<--- structure that 
iterates, a for loop being the basic example), which does indeed work like 
this. (And that is mandated.) Cursors are references, rather similar to 
access values in Ada. They live individually. 

Regards,
Petter        



^ permalink raw reply	[relevance 9%]

* Re: Ada.Containers and concurrent modification exception.
  2018-09-25  6:04  9%           ` Petter Fryklund
@ 2018-09-25 22:32 17%             ` Randy Brukardt
  2018-09-26  5:01  9%               ` Petter Fryklund
  0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2018-09-25 22:32 UTC (permalink / raw)


"Petter Fryklund" <petter.fryklund@atero.se> wrote in message 
news:95d94212-9ae3-423e-980f-705fea24744d@googlegroups.com...
> Personally I prefer passive iterators:

Which has what to do with this discussion on tampering and dangling cursor 
checks? A passive iterator still needs a tampering check.

Note that the Ada.Containers have these sort of iterators (in the form of 
iterators with access-to-procedure parameters). And they have tampering 
checks.

                                                                     Randy.



^ permalink raw reply	[relevance 17%]

* Re: Ada.Containers and concurrent modification exception.
  2018-09-24 21:47  5%         ` Randy Brukardt
@ 2018-09-25  6:04  9%           ` Petter Fryklund
  2018-09-25 22:32 17%             ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Petter Fryklund @ 2018-09-25  6:04 UTC (permalink / raw)


Personally I prefer passive iterators:

The container has a 

generic
  with procedure Process(Item : in Item_Type; Continue : out Boolean);
procedure Traverse_Container;

The user instantiate the generic with:

procedure Process(Item : in Item_Type; Continue : out Boolean);

procedure Travers is new Traverse_Container(Process);

And then implements the body of Process.

^ permalink raw reply	[relevance 9%]

* Re: Ada.Containers and concurrent modification exception.
    2018-09-22  8:05  8%         ` Dmitry A. Kazakov
@ 2018-09-24 21:47  5%         ` Randy Brukardt
  2018-09-25  6:04  9%           ` Petter Fryklund
  1 sibling, 1 reply; 200+ results
From: Randy Brukardt @ 2018-09-24 21:47 UTC (permalink / raw)


<rakusu_klein@fastmail.jp> wrote in message 
news:b41ee5c2-3000-442f-93cf-67116eac833a@googlegroups.com...
???????, 22 ???????? 2018 ?., 2:27:59 UTC+3 ???????????? Randy Brukardt 
???????:
>> And it would be wrong: deleting a node from the Map only invalidates 
>> cursors
>> that point at that node, not cursors that point at other nodes in the 
>> Map.
>> Those can continue to be used (for instance, if stored in another 
>> container)
>> until their nodes or the map as a whole are deleted.
>
>You missed the point, perhaps because I choose obscure names for 
>properties. Sorry.

No, I understood the point quite well. It doesn't work. Consider the 
following Ada pseudo-code (which you ought to be able to understand 
regardless of any language barrier):

    M : Map;
    R1, R2 : Cursor;

    M.Insert (..., R1); -- Insert a record saving the cursor. Mod counter = 
1.
    M.Insert (..., R2); -- Mod counter = 2.
    M.Delete (R1); -- Oops, cursor is invalid, container was modifed since 
it was created -- but this must work.
    ... Element (R2) ...; -- Oops, cursor is invalid, container was modifed 
since it was created, but this must work.
    ... Element (R1) ...; -- Cursor is invalid, OK to have raise an error 
here.

The important point is that a cursor remains valid until either the 
container as a whole or the element it designated is deleted. Thus, if you 
were to use some sort of counter implementation, it has to be per-node (that 
is, per-element).

In addition, some container operations (especially with lists) allow moving 
nodes from one container to another, so the counter has to be global to all 
of the containers of a particular type. This brings tasking issues into it.

Unlikely Dmitry, I think this check can be done usefully, *but* it can't be 
done in a way which is 100% accurate. False positives (that is, errors in 
correct cases) cannot be tolerated, so it necessarily has to be 
conservative.

...
>> when a container is destroyed and a new one created in the same location
>It will be created with zero number of modifications. If iterator will have 
>zero number
>of modifications too, nothing wrong happens (just because container is 
>empty),
>otherwise exception will be raised.

As noted above, the counter has to be per-element and global to all 
containers of a given type (at least for some types of containers). So 
resetting for each container doesn't work.

>> It also could fail if the counter wrapped arround
>Why? We just need to check if the value of Known_Modifications in iterator 
>...

We're not talking about "iterators", we're talking about cursors. Iterators 
have the tampering check (an iterator being an active structure that 
iterates, a for loop being the basic example), which does indeed work like 
this. (And that is mandated.) Cursors are references, rather similar to 
access values in Ada. They live individually.

>...is equal to the value of Actual_Modifications in container. It is the 
>reason why I called
>they both a State - an unique number that reflects a number of container's 
>modifications.
>And on a 32-bit machine we have a 4_294_967_296 modifications before a 
>wrap.

Remember, this check has to be per-element, as detailed above. Then consider 
a long-lived program (like a web server, which may run weeks or months) and 
a data structure that might be modified thousands of times per second. I 
agree that this is not very likely, but a check based on such a counter 
cannot detect all possible errors -- 99.9999% perhaps, but that is not a 
appropriate answer to a requirement. (And it will be much less effective if 
the memory is returned to the system when nodes are deleted.)

>Of course, there is a possibility of check failure exists, but it has very 
>low probability.

Too high in my view to consider it a solution for cursor checks. Especially 
as they cannot be effective once the memory of the designated node is 
reclaimed. (For the Janus/Ada implementation, we will delay reclaimation 
among other tricks to maximize detection, but it's far from perfect.)

                                          Randy.




^ permalink raw reply	[relevance 5%]

* Re: Ada.Containers and concurrent modification exception.
  2018-09-22 17:49  9%           ` rakusu_klein
@ 2018-09-22 19:50  9%             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2018-09-22 19:50 UTC (permalink / raw)


On 2018-09-22 19:49, rakusu_klein@fastmail.jp wrote:
> Hello. Did you speak Russian?

I certainly did. (:-))

> I do not understand what's going on, so I need help.

If I can, I don't use the library containers.

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


^ permalink raw reply	[relevance 9%]

* Re: Ada.Containers and concurrent modification exception.
  2018-09-22  8:05  8%         ` Dmitry A. Kazakov
@ 2018-09-22 17:49  9%           ` rakusu_klein
  2018-09-22 19:50  9%             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: rakusu_klein @ 2018-09-22 17:49 UTC (permalink / raw)


Hello. Did you speak Russian? I do not understand what's going on, so I need help.

^ permalink raw reply	[relevance 9%]

* Re: Ada.Containers and concurrent modification exception.
  @ 2018-09-22  8:05  8%         ` Dmitry A. Kazakov
  2018-09-22 17:49  9%           ` rakusu_klein
  2018-09-24 21:47  5%         ` Randy Brukardt
  1 sibling, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2018-09-22  8:05 UTC (permalink / raw)


On 2018-09-22 03:09, rakusu_klein@fastmail.jp wrote:
> суббота, 22 сентября 2018 г., 2:27:59 UTC+3 пользователь Randy Brukardt написал:
>> And it would be wrong: deleting a node from the Map only invalidates cursors
>> that point at that node, not cursors that point at other nodes in the Map.
>> Those can continue to be used (for instance, if stored in another container)
>> until their nodes or the map as a whole are deleted.
> 
> You missed the point, perhaps because I choose obscure names for properties. Sorry.
> 
> State_Type is a modification's counter with a wrap-around sematic. It counts modifications of an internal container's structure and exists in all container's instances (call them Actual_Modifications) and in every iterator's instance (call them Known_Modifications). When an iterator is created for an existing container, its counter is initialized by value of that container, so their values are equal. When container is changed by any public method, its modification counter is incremented by one. If modification process by public method involves an iterator, the modification counter inside the iterator also incremented by one. Before any modification will doing, values of counters for container and iterator will be compared for equality, and if The_Container.Actual_Modifications /= The_Cursor.Known_Modifications then raise Concurent_Modification.

This schema (sequence numbers) would invalidate all cursors. Not a good 
idea at all, in presence of many cursors. If there is only one cursor 
then there is also no problem. So the case looks quite marginal to me.

If I wanted to cover it, provided I ever used cursors, I would rather 
have the task ID to identify the owner of the change. This would be sort 
of re-entrant mutex with the difference that it would raise exception 
instead of blocking the offender.

In short:

1. The whole idea of fine interlocking/detection of concurrent access at 
the granularity level of individual container elements is wrong. It will 
never work, IMO.

2. The idea of raising exceptions concurrently at run-time to indicate 
tasking design errors is even worse.

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

^ permalink raw reply	[relevance 8%]

Results 1-200 of ~2000   | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2018-09-19 13:12     Ada.Containers and concurrent modification exception rakusu_klein
2018-09-19 15:53     ` Simon Wright
2018-09-19 18:24       ` rakusu_klein
2018-09-21 23:27         ` Randy Brukardt
2018-09-22  1:09           ` rakusu_klein
2018-09-22  8:05  8%         ` Dmitry A. Kazakov
2018-09-22 17:49  9%           ` rakusu_klein
2018-09-22 19:50  9%             ` Dmitry A. Kazakov
2018-09-24 21:47  5%         ` Randy Brukardt
2018-09-25  6:04  9%           ` Petter Fryklund
2018-09-25 22:32 17%             ` Randy Brukardt
2018-09-26  5:01  9%               ` Petter Fryklund
2018-11-10 10:36 10% "Equality operator appears too late" JLotty
2018-11-10 13:34  7% ` joakimds
2018-11-10 14:36  0%   ` JLotty
2018-11-11  6:32  0%   ` Randy Brukardt
2018-11-11 20:05  0%     ` Simon Wright
2019-03-12 11:47  0% ` Simon Wright
2018-12-12 14:04     Graph database client? eg Neo4j, Dgraph Olivier Henley
2018-12-13 23:15 10% ` Shark8
2018-12-15  0:59  0%   ` Olivier Henley
2018-12-16 18:23  7%     ` Shark8
2019-08-20 15:13  0%     ` Shark8
2022-12-22 13:16  0%       ` Marius Amado-Alves
2018-12-22  5:37  7% Сreate attributes eduardsapotski
2018-12-22 19:13  0% ` Brad Moore
2019-01-02 15:48  4% class wide iterable (and indexable) George Shapovalov
2019-01-02 17:39  6% ` Simon Wright
2019-01-02 18:11  9%   ` George Shapovalov
2019-01-03  8:52 11%     ` Simon Wright
2019-01-03  9:30  6%       ` George Shapovalov
2019-01-04  4:32  0%       ` Shark8
2019-01-05  9:03  0%         ` Randy Brukardt
2019-01-03 22:56  0%     ` Randy Brukardt
2019-01-04  0:00  4%       ` George Shapovalov
2019-01-04  8:43             ` Dmitry A. Kazakov
2019-01-04 12:20               ` George Shapovalov
2019-01-05 23:29                 ` Jere
2019-01-05 23:50                   ` Jere
2019-01-06  9:34  6%                 ` George Shapovalov
2019-01-05  9:21               ` Randy Brukardt
2019-01-05 10:07                 ` Dmitry A. Kazakov
2019-01-05 18:17  5%               ` George Shapovalov
2019-01-26 22:11  4% ` George Shapovalov
2019-01-25  9:43  5% Why forbid local generic instantiations? joakimds
2019-02-25 22:32     warehouse automation in ADA? robots? Rabican
2019-02-26  9:14     ` Björn Lundin
2019-02-27 10:28       ` Jesper Quorning
2019-02-27 12:30  6%     ` Björn Lundin
2019-03-08 16:43     Intervention needed? Olivier Henley
2019-03-08 17:31  7% ` gautier_niouzes
2019-03-11 14:31  0%   ` antispam
2019-03-11 15:34     ` Lucretia
2019-03-11 22:08       ` Jeffrey R. Carter
2019-03-12  2:04         ` Lucretia
2019-03-12 16:32           ` Jeffrey R. Carter
2019-03-12 18:14             ` Olivier Henley
2019-03-12 19:21               ` Lucretia
2019-03-12 21:53                 ` Randy Brukardt
2019-03-17 12:52                   ` Optikos
2019-03-18 23:36                     ` Randy Brukardt
2019-03-19  2:18                       ` Optikos
2019-03-19  8:44                         ` Dmitry A. Kazakov
2019-03-19  9:53                           ` Optikos
2019-03-19 22:13                             ` Randy Brukardt
2019-03-19 22:26                               ` Paul Rubin
2019-03-20  1:08                                 ` Jere
2019-03-22  2:26  9%                               ` Randy Brukardt
2019-03-19 22:36                               ` Optikos
2019-03-19 23:13                                 ` Randy Brukardt
2019-03-20  1:28                                   ` Jere
2019-03-22  2:00  8%                                 ` Randy Brukardt
2019-03-20  1:20                               ` Jere
2019-03-22  2:30  7%                             ` Randy Brukardt
2019-03-19  9:37                         ` Optikos
2019-03-19 22:21  9%                       ` Randy Brukardt
2019-03-29 17:56                       ` Florian Weimer
2019-03-29 22:17                         ` Randy Brukardt
2019-03-29 22:35  7%                       ` Florian Weimer
2019-04-01 21:17  0%                         ` Randy Brukardt
2019-03-17 20:43  9% How to access Vector.Index_Type? jakub.dabek
2019-03-17 21:25  0% ` Simon Wright
2019-03-18  4:17  7% ` gautier_niouzes
2019-03-18  5:27  0% ` J-P. Rosen
2019-03-18  8:31  0%   ` Dmitry A. Kazakov
2019-03-18 19:35  0% ` Jeffrey R. Carter
2019-06-25  8:21     recursive map specification mario.blunk.gplus
2019-06-25  8:44  7% ` Egil H H
2019-06-25  9:09  0%   ` mario.blunk.gplus
2019-06-25  9:22  0%     ` Egil H H
2019-06-25  9:24  0%       ` mario.blunk.gplus
2019-10-08 15:46  6% Funny (so to say...) interaction of "not null" and Vectors? mockturtle
2019-10-14 19:41     How to transfer Class-Wide object to a Task ? William FRANCK
2019-10-14 19:58     ` Dmitry A. Kazakov
2019-10-14 20:58       ` William FRANCK
2019-10-15  4:40 10%     ` Per Sandberg
2019-10-15  5:40  0%       ` William FRANCK
2019-10-16 20:04  7%       ` William FRANCK
2019-10-17  9:28  9%         ` William FRANCK
2019-10-15 14:31         ` Optikos
2019-10-15 19:41  6%       ` William FRANCK
2019-10-14 20:21     ` William FRANCK
2019-10-14 21:57  6%   ` Shark8
2019-10-15  5:43  0%     ` William FRANCK
2019-10-29 13:43 10% How to Iterate over all elements of a hashed_map Alain De Vos
2019-10-29 14:20  9% ` Alain De Vos
2019-10-29 15:02  0%   ` joakimds
2019-10-29 21:56  0%     ` Randy Brukardt
2019-10-29 16:48  0% ` Jeffrey R. Carter
2019-10-31 17:17     tokyocabinet,redis,mongodb,couchdb,influxdb,timescaledb connectors Alain De Vos
2019-11-01 13:51  9% ` Shark8
2019-11-01 14:39  0%   ` Alain De Vos
2022-12-22 13:10  0%   ` Marius Amado-Alves
2019-11-04 16:45     how would gnoga.com beat www.tck.tk and postgresql on freebsd? Azathoth Hastur
2019-11-05 17:11  7% ` Shark8
2019-11-07 13:27  7%   ` Azathoth Hastur
2019-11-07 14:21  8%     ` Dmitry A. Kazakov
2019-11-07 23:14  0%       ` Azathoth Hastur
2019-11-22 13:26  5% yes another gnat bug (inherited tagged type as record field is too much for gnat??) gerrshapovalov
2019-12-04 13:56     Type naming conventions: Any_Foo Alejandro R. Mosteo
2019-12-04 14:52     ` Lucretia
2019-12-04 16:42       ` Alejandro R. Mosteo
2019-12-05 10:51         ` AdaMagica
2019-12-05 17:27           ` Jeffrey R. Carter
2019-12-05 17:45             ` Dmitry A. Kazakov
2019-12-05 20:03               ` Jeffrey R. Carter
2019-12-05 21:51  7%             ` Dmitry A. Kazakov
2019-12-06 20:18  0%               ` Jeffrey R. Carter
2019-12-06 20:35  0%                 ` Dmitry A. Kazakov
2019-12-07  0:57  7%                   ` Randy Brukardt
2019-12-07 10:28  0%                     ` Jeffrey R. Carter
2019-12-07 12:36  0%                       ` Niklas Holsti
2019-12-11 16:43  7% Is this actually possible? Lucretia
2019-12-11 17:38     ` Dmitry A. Kazakov
2019-12-11 17:54       ` Lucretia
2019-12-11 19:58         ` Dmitry A. Kazakov
2019-12-11 21:12           ` Lucretia
2019-12-11 21:34             ` Dmitry A. Kazakov
2019-12-12  2:00  7%           ` Randy Brukardt
2019-12-12  9:26  0%             ` Niklas Holsti
2020-04-08 16:10  0%             ` Alejandro R. Mosteo
2019-12-11 19:59  0% ` Randy Brukardt
2020-01-14 15:27     Tally Gilbert Gosseyn
2020-01-14 21:08     ` Tally Jeffrey R. Carter
2020-01-15  3:40  9%   ` Tally Brad Moore
2020-01-26 10:23     Simple Components: adding an existing object to a graph Mart van de Wege
2020-01-26 14:48  7% ` Jeffrey R. Carter
2020-01-26 15:39  0%   ` Mart van de Wege
2020-01-26 15:49  0%   ` Mart van de Wege
2020-02-18  1:37  8% use type does not seem to work for types in generic package instantiations yoehoduv
2020-02-20 12:24  9% Different aliasing rules for containers? Martin B. B.
2020-02-20 13:36  0% ` joakimds
2020-02-20 13:47  0%   ` Martin B. B.
2020-03-09 16:43  8% Containers, dangling references Simon Wright
2020-03-17 12:31     multidimensional sort Gilbert Gosseyn
2020-03-17 12:56  7% ` Petter Fryklund
2020-03-17 17:24  9%   ` Simon Wright
2020-03-17 20:16  0%     ` Simon Wright
2020-03-23 23:16     GNAT vs Matlab - operation on multidimensional complex matrices darek
2020-06-08 17:42  4% ` Shark8
2020-04-03 22:48     Proposal: Auto-allocation of Indefinite Objects Stephen Davies
2020-07-27  7:47     ` Yannick Moy
2020-07-27 17:48       ` Brian Drummond
2020-07-27 20:31 10%     ` Jeffrey R. Carter
2020-04-12 12:32  8% Generic oddness Per Jakobsen
2020-04-12 16:38  0% ` Ludovic Brenta
2020-04-14  7:15     Put the access value ldries46
2020-04-14 11:05  6% ` Jeffrey R. Carter
2020-04-14 12:09  0%   ` ldries46
2020-06-06 23:40  7% CONSTRAINT ERROR: erroneous memory access jcupak
2020-06-07 15:53  0% ` Anh Vo
2020-06-16 11:31     How can I get this data into the .data section of the binary? Luke A. Guest
2020-06-16 14:14     ` Niklas Holsti
2020-06-16 14:25       ` Dmitry A. Kazakov
2020-06-16 14:42         ` Luke A. Guest
2020-06-16 15:21           ` Dmitry A. Kazakov
2020-06-16 15:43             ` Luke A. Guest
2020-06-16 16:11  7%           ` Dmitry A. Kazakov
2020-08-06 18:40     Newbie question # 2 Ian Douglas
2020-08-06 18:56  7% ` Simon Wright
2020-08-06 19:41  0%   ` Ian Douglas
2020-09-11 10:37     Visibility issue Daniel
2020-09-17 21:47  6% ` Shark8
2020-11-25 14:08 10% Dueling Compilers Jeffrey R. Carter
2020-11-26  2:19  0% ` Randy Brukardt
2020-12-02 15:41  0% ` Shark8
2020-12-05 14:54     Advent of Code day 5 Stephen Leake
2020-12-06  9:14     ` Jeffrey R. Carter
2020-12-06 14:09       ` Björn Lundin
2020-12-06 16:21  7%     ` Stephen Leake
2020-12-06 16:27  0%       ` Stephen Leake
2020-12-06 21:09  7%       ` Björn Lundin
2020-12-09  1:18  0%         ` Stephen Leake
2020-12-06  8:39     Advent of Code Day 6 John Perry
2020-12-06 11:07  7% ` Jeffrey R. Carter
2020-12-06 19:37  9%   ` John Perry
2021-01-05 11:04     Lower bounds of Strings Stephen Davies
2021-01-06  3:08     ` Randy Brukardt
2021-01-06  9:13       ` Dmitry A. Kazakov
2021-01-07  0:17  8%     ` Randy Brukardt
2021-01-07  9:57  0%       ` Dmitry A. Kazakov
2021-01-07 22:03             ` Randy Brukardt
2021-01-08 17:23               ` Shark8
2021-01-08 20:19                 ` Dmitry A. Kazakov
2021-01-09  2:18                   ` Randy Brukardt
2021-01-09 10:53  6%                 ` Dmitry A. Kazakov
2021-02-03 17:47     specifying only 'First of an index in an array Mehdi Saada
2021-02-03 19:29  7% ` Jeffrey R. Carter
2021-02-20 15:26     set_index and and end_of_file with just a stream reference Mehdi Saada
2021-02-20 16:04     ` Dmitry A. Kazakov
2021-02-20 16:22       ` Mehdi Saada
2021-02-20 16:30         ` Mehdi Saada
2021-02-20 17:59           ` Dmitry A. Kazakov
2021-02-20 19:08             ` Mehdi Saada
2021-02-23 17:21  8%           ` Shark8
     [not found]     <602e608e$0$27680$e4fe514c@news.kpn.nl>
2021-02-25 12:43     ` Alternative for Gnat Studio ldries46
2021-02-26  7:56       ` Dmitry A. Kazakov
2021-02-28 22:54         ` Stephen Leake
2021-03-02  5:11           ` John Perry
2021-03-02  8:08             ` Emmanuel Briot
2021-03-02  9:13               ` rr (was: Re: Alternative for Gnat Studio) Simon Wright
2021-03-02  9:23                 ` Emmanuel Briot
2021-03-04 22:48  7%               ` rr Simon Wright
2021-03-12 20:49     array from static predicate on enumerated type Matt Borchers
2021-03-12 22:41     ` Dmitry A. Kazakov
2021-03-13  2:06       ` Matt Borchers
2021-03-13  4:55         ` Randy Brukardt
2021-03-15 14:16           ` Matt Borchers
2021-03-15 17:53  7%         ` Shark8
2021-03-13  8:04         ` Dmitry A. Kazakov
2021-03-15 14:11           ` Matt Borchers
2021-03-15 17:48             ` Shark8
2021-03-15 20:25               ` Dmitry A. Kazakov
2022-03-16  0:38  9%             ` Thomas
2021-04-17 21:45     Unchecked_Deallocation with tagged types DrPi
2021-04-18  8:21     ` Dmitry A. Kazakov
2021-04-18  8:46       ` Gautier write-only address
2021-04-18  9:09         ` Jeffrey R. Carter
2021-04-18 10:20           ` J-P. Rosen
2021-04-18 10:34             ` Dmitry A. Kazakov
2021-04-18 15:14               ` J-P. Rosen
2021-04-18 15:23                 ` Gautier write-only address
2021-04-20 18:53                   ` Randy Brukardt
2021-04-20 19:35                     ` Dmitry A. Kazakov
2022-04-18  5:51  7%                   ` Thomas
2021-04-20 20:32                     ` Jeffrey R. Carter
2021-04-20 21:10                       ` Niklas Holsti
2021-04-24  0:49                         ` Randy Brukardt
2022-04-18  1:51 10%                       ` Thomas
2021-04-18  9:13       ` DrPi
2021-04-18 16:48         ` Jeffrey R. Carter
2021-04-20 15:57           ` Stephen Leake
2021-04-20 17:24             ` Jeffrey R. Carter
2021-04-20 17:34               ` Vincent Marciante
2021-04-20 20:56                 ` Jeffrey R. Carter
2021-04-21 10:21                   ` Vincent Marciante
2021-04-24  1:04                     ` Randy Brukardt
2022-04-12 23:25  7%                   ` use clauses Thomas
2022-04-13  1:05  0%                     ` Randy Brukardt
2021-04-17 22:03     Ada and Unicode DrPi
2021-04-19  9:08     ` Stephen Leake
2021-04-19 11:56       ` Luke A. Guest
2021-04-19 12:52         ` Dmitry A. Kazakov
2021-04-19 13:00           ` Luke A. Guest
2021-04-20 19:06             ` Randy Brukardt
2022-04-03 18:37               ` Thomas
2022-04-04 23:52                 ` Randy Brukardt
2023-03-31  3:06  6%               ` Thomas
2023-04-01 10:18  0%                 ` Randy Brukardt
2021-05-03 16:08     GCC 11 bug? lawyer needed Simon Wright
2021-05-05  3:54     ` Randy Brukardt
2021-05-05 10:01       ` AdaMagica
2021-05-05 16:10         ` AdaMagica
2021-05-06  0:39           ` Randy Brukardt
2021-05-06 20:02  9%         ` Simon Wright
2021-05-06 20:51  0%           ` Dmitry A. Kazakov
2021-05-06 23:59  0%           ` Randy Brukardt
2021-07-17  7:56     Problem with emacs ada-mode-7.1.4 Paul Onions
2021-07-17 21:18     ` Simon Wright
2021-07-18  8:43       ` Paul Onions
2021-07-18  9:00         ` Dmitry A. Kazakov
2021-07-18  9:26           ` Paul Onions
2021-07-18 13:28             ` Paul Onions
2021-07-18 16:24  6%           ` Simon Wright
2021-07-19 21:17  0%             ` Stephen Leake
2022-04-30  8:57 10% Question on in/out parameters reinert
2022-06-13 21:49  7% Bugged Multiway_Tree package? Devin Rozsas
2022-08-25 10:01     yet another Ada web site? Maxim Reznik
2022-08-27  9:12     ` Rene
2022-08-27  9:53       ` Nasser M. Abbasi
2022-08-28  7:50         ` Dmitry A. Kazakov
2022-08-28 10:26           ` Luke A. Guest
2022-09-16 15:25             ` Maxim Reznik
2022-09-17 13:08               ` Move semantics (was: yet another Ada web site?) G.B.
2022-09-19 17:04                 ` Move semantics Stephen Leake
2022-09-19 18:50                   ` Paul Rubin
2022-09-20 11:44                     ` AdaMagica
2022-09-20 14:46 10%                   ` Niklas Holsti
2022-08-31  8:15     Calling inherited primitive operations in Ada Emmanuel Briot
2022-08-31 19:13     ` Dmitry A. Kazakov
2022-09-01  6:56       ` Emmanuel Briot
     [not found]         ` <67b32db0-c4db-466c-ac13-e597e008c762n@googlegroups.com>
2022-09-01 11:59           ` Jeffrey R.Carter
2022-09-01 12:37             ` Dmitry A. Kazakov
2022-09-01 13:37               ` Jeffrey R.Carter
2022-09-01 14:10                 ` Emmanuel Briot
2022-09-01 16:03                   ` Jeffrey R.Carter
2022-09-01 16:07                     ` Emmanuel Briot
2022-09-01 16:17                       ` Jeffrey R.Carter
2022-09-01 18:54                         ` Emmanuel Briot
2022-09-01 21:33                           ` Jeffrey R.Carter
2022-09-02  6:11  8%                         ` Emmanuel Briot
2022-09-02 10:55  0%                           ` Jeffrey R.Carter
2022-09-03  0:07 10%                           ` Randy Brukardt
2022-09-03 19:00 10%                             ` Simon Wright
2022-09-05  6:56 10%                               ` Emmanuel Briot
2022-09-05  7:34  0%                                 ` Dmitry A. Kazakov
2022-09-05  9:30  6%                                 ` Jeffrey R.Carter
2022-09-14 12:36 18% Non-standard functions in GNAT's Ada.Containers packages? G.B.
2022-09-14 16:04  9% ` Egil H H
2022-09-15  7:13  9%   ` G.B.
2022-09-15 14:26  9%     ` Marius Amado-Alves
2022-09-15 15:03  8%       ` Niklas Holsti
2022-09-15 17:11  9%         ` Marius Amado-Alves
2022-09-15 17:22  9%           ` Dmitry A. Kazakov
2022-09-16 16:03  8%             ` Marius Amado-Alves
2022-09-16 16:30  9%               ` Marius Amado-Alves
2022-09-16 17:08 18%                 ` Jere
2022-09-16 11:33 19%           ` Björn Lundin
2022-09-16 15:00  9%             ` Marius Amado-Alves
2022-09-16 15:42 17%               ` Egil H H
2022-09-16 18:53 18%               ` Björn Lundin
2022-09-16 15:47 17%           ` Jere
2022-09-26  6:54  9% Compiler error (2) ? reinert
2022-09-26  8:12  5% ` Simon Wright
2022-09-26  8:34  0% ` J-P. Rosen
2022-09-26  8:47 10%   ` reinert
2022-09-26  9:59  0%     ` reinert
2023-01-22 21:34     Real_Arrays on heap with overloaded operators and clean syntax Jim Paloander
2023-01-24 19:47  7% ` Gautier write-only address
2023-01-26 20:39     ` Jerry
2023-01-26 21:52  5%   ` Jim Paloander
2023-02-02 21:59  0%     ` Jerry
2023-02-14  8:49 19% Use Ada.Containers.Vectors Generic_Sorting or Ada.Containers.Ordered_Sets ? reinert
2023-02-14  9:35 11% ` Jeffrey R.Carter
2023-02-14 10:46 12%   ` reinert
2023-02-14 18:48 11%     ` G.B.
2023-03-15 10:05 12% ` Marius Amado-Alves
2023-03-15 14:24 11% ` Brad Moore
2023-03-19  6:17  7% Is this a compiler bug ? Rod Kay
2023-04-17 14:20     Hi guys! I've been inactive for a long time but now started to develop a hobby application. I found a strange behaviour with gdb. Locally renaming a function S in order to shorten the source code visits cygwin.S during execution. thie is very awkwae Petter
2023-04-17 15:05     ` Niklas Holsti
2023-04-17 15:19       ` Simon Wright
2023-04-17 19:39         ` Chris Townley
2023-04-18 11:18  6%       ` Hi guys! I've been inactive for a long time but now started to develop a hobby application. I found a strange behaviour with gdb. Locally renaming a function S in order to shorten the source code visits cygwin.S during execution. thie is very awk Petter
2023-07-14 19:17 10% Formal Package Compiler Differences Jeffrey R.Carter
2023-07-14 19:27  0% ` Jeffrey R.Carter
2023-09-04  9:19     project euler 26 CSYH (QAQ)
2023-09-04 11:06     ` Niklas Holsti
2023-09-04 12:39       ` Dmitry A. Kazakov
2023-09-04 16:01         ` Ben Bacarisse
2023-09-04 19:20           ` Dmitry A. Kazakov
2023-09-04 20:18             ` Ben Bacarisse
2023-09-04 21:00               ` Dmitry A. Kazakov
2023-09-04 23:16  8%             ` Ben Bacarisse
2023-09-05  7:23  0%               ` Dmitry A. Kazakov
2023-09-05 15:18  0%                 ` Ben Bacarisse
2023-09-05 17:08                       ` Dmitry A. Kazakov
2023-09-06  1:10                         ` Ben Bacarisse
2023-09-06  7:06                           ` Dmitry A. Kazakov
2023-09-06 15:16                             ` Ben Bacarisse
2023-09-06 15:54  9%                           ` Dmitry A. Kazakov
2023-09-06 23:32  0%                             ` Ben Bacarisse
2023-09-07  9:02  7%                               ` Dmitry A. Kazakov
2023-09-08  1:32  0%                                 ` Ben Bacarisse
2023-09-08  7:23  0%                                   ` Dmitry A. Kazakov
2023-09-09  0:25  0%                                     ` Ben Bacarisse
2023-09-09  9:32  4%                                       ` Dmitry A. Kazakov
2023-09-10  1:20  0%                                         ` Ben Bacarisse
2023-09-08  6:09                                   ` G.B.
2023-09-08 21:02                                     ` Ben Bacarisse
2023-09-09  8:13  8%                                   ` G.B.
2023-09-05 17:35  0%                 ` moi
2023-09-14 14:02  8% Aggregate with derived types Blady
2023-09-14 15:31  0% ` Jeffrey R.Carter
2023-09-14 20:00  0%   ` Blady
2023-09-22  6:25  9% What I do wrong here? reinert
2023-12-28 13:53     Map iteration and modification DrPi
2023-12-28 13:59     ` DrPi
2023-12-28 16:06       ` Dmitry A. Kazakov
2023-12-29  3:20         ` Randy Brukardt
2023-12-29  9:51           ` Dmitry A. Kazakov
2023-12-29 15:03             ` G.B.
2023-12-29 16:52               ` Dmitry A. Kazakov
2024-01-01 19:27  8%             ` G.B.
2024-01-01 20:55  0%               ` Dmitry A. Kazakov
2023-12-30  7:21             ` Randy Brukardt
2023-12-30 11:07               ` Dmitry A. Kazakov
2024-01-03  3:15                 ` Randy Brukardt
2024-01-03 10:04                   ` Dmitry A. Kazakov
2024-01-04  4:07  9%                 ` Randy Brukardt
2024-01-04 11:28  0%                   ` Dmitry A. Kazakov

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