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: Unchecked_Deallocation with tagged types
  @ 2022-04-18  1:51  8%                       ` Thomas
  0 siblings, 0 replies; 94+ 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 8%]

* Re: Advent of Code day 5
  @ 2020-12-06 21:09  8%       ` Björn Lundin
  0 siblings, 0 replies; 94+ 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 8%]

* Re: Put the access value
  2020-04-14 11:05  7% ` Jeffrey R. Carter
@ 2020-04-14 12:09  0%   ` ldries46
  0 siblings, 0 replies; 94+ 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  7% ` Jeffrey R. Carter
  2020-04-14 12:09  0%   ` ldries46
  0 siblings, 1 reply; 94+ 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 7%]

* Re: Generic oddness
  2020-04-12 12:32 10% Generic oddness Per Jakobsen
@ 2020-04-12 16:38  0% ` Ludovic Brenta
  0 siblings, 0 replies; 94+ 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 10% Per Jakobsen
  2020-04-12 16:38  0% ` Ludovic Brenta
  0 siblings, 1 reply; 94+ 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 10%]

* Re: grassroots thoughts on access types
  @ 2018-02-10 15:32  8%                   ` Jeffrey R. Carter
  0 siblings, 0 replies; 94+ results
From: Jeffrey R. Carter @ 2018-02-10 15:32 UTC (permalink / raw)


On 02/10/2018 12:57 PM, Mehdi Saada wrote:
> while we're at it, how would I write in SPARK
> type Cell is
>     record
>        Next: access Cell;
>        Value: Integer;
>     end record;

You can't. SPARK doesn't have access types.

You could build a bounded list instead, or put a SPARK wrapper around 
Ada.Containers.Doubly_Linked_Lists (if you accept that it's correct).

-- 
Jeff Carter
"What lazy lout left these wires all over the lawn?"
Poppy
98

^ permalink raw reply	[relevance 8%]

* Re: Iterable container as generic parameter
  @ 2018-01-25 14:58 11%   ` Lionel Draghi
  0 siblings, 0 replies; 94+ results
From: Lionel Draghi @ 2018-01-25 14:58 UTC (permalink / raw)


> As to the question you didn't ask, you clearly need the container type 
> somewhere in your interface, so you can pass container objects. (Or, I 
> suppose, you could reference the type used in the instance of the 
> Iterator_Interfaces.) Otherwise, you just have methods but no data. And 
> there isn't anything interesting that you can do with just methods!
> 
>                                     Randy.

Thanks Randy for the answer, this is actually my question.
And what you put into parenthesis was what I was trying to do.

Here is my point : 
If I limit the procedure scope to a specific container, the generic is simple : 

with Ada.Containers.Doubly_Linked_Lists;
generic
   type Element_Type is (<>);
   with function Image (Element : Element_Type) return String is <>;
   with package Lists is new Ada.Containers.Doubly_Linked_Lists (Element_Type);
function List_Image_1 (List : Lists.List) return string;

But if want something that could be used with both Lists and Maps, I have to provide much more parameters : 

with Ada.Containers;
generic
   type Element_Type (<>) is Private;
   with function Image (Element : Element_Type) return String is <>;

   type Cursor is private; 
   with function First return Cursor is <>;
   with function Next (Position : Cursor) return Cursor is <>;
   with function Length return Ada.Containers.Count_Type is <>;

   with function Element (Position : Cursor) return Element_Type is <>;

function List_Image_2 return String;

And that sounds a bit to complex to me, because what I am doing is just creating my own iterator. 
This is why I was trying to simplify the generic formal part by using the Iterator_Interfaces.

I have the feeling that I’m missing something.

Lionel

PS : here is my test code.

with Ada.Containers.Doubly_Linked_Lists;

generic
   type Element_Type is (<>);
   with function Image (Element : Element_Type) return String is <>;
   with package Lists is new Ada.Containers.Doubly_Linked_Lists (Element_Type);

function List_Image_1 (List : Lists.List) return string;

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

function List_Image_1 (List : Lists.List) return String is
   Tmp : Unbounded_String;
begin
   for E of List loop
      Tmp := Tmp & " " & Image (E);
   end loop;
   return To_String (Tmp);
end List_Image_1;

with Ada.Containers;

generic
   type Element_Type (<>) is Private;
   with function Image (Element : Element_Type) return String is <>;

   type Cursor is private; 
   with function First return Cursor is <>;
   with function Next (Position : Cursor) return Cursor is <>;
   with function Length return Ada.Containers.Count_Type is <>;
   
   with function Element (Position : Cursor) return Element_Type is <>;
   
function List_Image_2 return String;

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

function List_Image_2 return String is
   Tmp : Unbounded_String;
   C   : Cursor;
begin
   -- a bit more sophisticated format
   case Length is 
      when 0 => return "";
      when 1 => return "[" & Image (Element (First)) & "]";
      when others => 
         C := First;
         Tmp := To_Unbounded_String ("[") & Image (Element (C));
         for I in 2 .. Length loop
            C := Next (C);
            Tmp := Tmp  & ", " & Image (Element (C));
         end loop;
         Tmp := Tmp & "]";
   end case;
   return To_String (Tmp);
end List_Image_2;

with List_Image_1;
with List_Image_2;

with Ada.Containers.Doubly_Linked_Lists;
with Ada.Containers.Indefinite_Hashed_Sets;
with Ada.Strings.Hash_Case_Insensitive;

with Ada.Text_Io;

procedure Test_List_Image is
   
   -- container for test purposes
   package Integer_Lists is new Ada.Containers.Doubly_Linked_Lists (Integer);
   List : Integer_Lists.List;

   Function Integer_List_Image_1 is new List_Image_1 
     (Integer, 
      Integer'Image, 
      Integer_Lists);

   function Integer_List_Image_2 is new List_Image_2 
     (Integer, 
      Integer'Image, 
      Integer_Lists.Cursor,
      List.First,
      Integer_Lists.Next,
      List.Length,
      Integer_Lists.Element);

   -- another container 
   function Image (S : String) return String is (String (S));
   
   package Id_Sets is new Ada.Containers.Indefinite_Hashed_Sets 
     (String, Ada.Strings.Hash_Case_Insensitive, "=");
   Set : Id_Sets.Set;
   use Id_Sets; 
   
   function Id_Set_Image_2 is new List_Image_2 
     (String, 
      Image, 
      Cursor  => Id_Sets.Cursor,
      First   => Set.First,
      Next    => Id_Sets.Next,
      Length  => Set.Length,
      Element => Id_Sets.Element);

begin
   -- ----------------------------------------------------------------------
   Ada.Text_Io.Put_Line ("Test generic 1 on a list :");
   Ada.Text_Io.Put_Line (Integer_List_Image_1 (List));

   List.Append (1);
   Ada.Text_Io.Put_Line (Integer_List_Image_1 (List));

   List.Append (2);
   Ada.Text_Io.Put_Line (Integer_List_Image_1 (List));

   List.Append (3);
   Ada.Text_Io.Put_Line (Integer_List_Image_1 (List));
   Ada.Text_Io.New_Line;
   
   -- ----------------------------------------------------------------------
   Ada.Text_Io.Put_Line ("Test generic 2 on a list :");

   List.Clear;
   Ada.Text_Io.Put_Line (Integer_List_Image_2);

   List.Append (1);
   Ada.Text_Io.Put_Line (Integer_List_Image_2);

   List.Append (2);
   Ada.Text_Io.Put_Line (Integer_List_Image_2);

   List.Append (3);
   Ada.Text_Io.Put_Line (Integer_List_Image_2);
   Ada.Text_Io.New_Line;

   -- ----------------------------------------------------------------------
   Ada.Text_Io.Put_Line ("Test generic 2 on a set :");
   
   Ada.Text_Io.Put_Line (Id_Set_Image_2);
   Set.Insert ("Hyperion");
   
   Ada.Text_Io.Put_Line (Id_Set_Image_2);
   Set.Insert ("Endymion");
   
   Ada.Text_Io.Put_Line (Id_Set_Image_2);
   Set.Insert ("TechnoCore");

   Ada.Text_Io.Put_Line (Id_Set_Image_2);

end Test_List_Image;


^ permalink raw reply	[relevance 11%]

* Re: Convert between different container types
  2017-09-11 21:20  0% ` Victor Porton
@ 2017-10-02 23:29  0%   ` Randy Brukardt
  0 siblings, 0 replies; 94+ results
From: Randy Brukardt @ 2017-10-02 23:29 UTC (permalink / raw)


You can use stream operations Read and Write to convert between two similar 
containers, including between an unbounded and bounded container of the same 
kind (vector, list, map, etc.). Other containers are too different 
internally to be convertable; you'll have to write your own conversion 
routine as suggested by someone else.

                                Randy.

"Victor Porton" <porton@narod.ru> wrote in message 
news:op6uo0$suu$1@gioia.aioe.org...
> Victor Porton wrote:
>
>> What is the easiest way to convert between different container types, for
>> example between Ada.Containers.Doubly_Linked_Lists and
>> Ada.Containers.Indefinite_Vectors as well as between these types and 
>> plain
>> old Ada arrays?
>
> Sorry, typo: I would instead consider the case when both containers are
> indefinite or both are not indefinite.
>
> -- 
> Victor Porton - http://portonvictor.org 



^ permalink raw reply	[relevance 0%]

* Re: Convert between different container types
  2017-09-11 21:19  9% Convert between different container types Victor Porton
  2017-09-11 21:20  0% ` Victor Porton
@ 2017-09-11 21:36  0% ` Simon Wright
  1 sibling, 0 replies; 94+ results
From: Simon Wright @ 2017-09-11 21:36 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> What is the easiest way to convert between different container types, for 
> example between Ada.Containers.Doubly_Linked_Lists and 
> Ada.Containers.Indefinite_Vectors as well as between these types and plain 
> old Ada arrays?

for El of A loop
   B.Append (El);
end loop;


^ permalink raw reply	[relevance 0%]

* Re: Convert between different container types
  2017-09-11 21:19  9% Convert between different container types Victor Porton
@ 2017-09-11 21:20  0% ` Victor Porton
  2017-10-02 23:29  0%   ` Randy Brukardt
  2017-09-11 21:36  0% ` Simon Wright
  1 sibling, 1 reply; 94+ results
From: Victor Porton @ 2017-09-11 21:20 UTC (permalink / raw)


Victor Porton wrote:

> What is the easiest way to convert between different container types, for
> example between Ada.Containers.Doubly_Linked_Lists and
> Ada.Containers.Indefinite_Vectors as well as between these types and plain
> old Ada arrays?

Sorry, typo: I would instead consider the case when both containers are 
indefinite or both are not indefinite.

-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 0%]

* Convert between different container types
@ 2017-09-11 21:19  9% Victor Porton
  2017-09-11 21:20  0% ` Victor Porton
  2017-09-11 21:36  0% ` Simon Wright
  0 siblings, 2 replies; 94+ results
From: Victor Porton @ 2017-09-11 21:19 UTC (permalink / raw)


What is the easiest way to convert between different container types, for 
example between Ada.Containers.Doubly_Linked_Lists and 
Ada.Containers.Indefinite_Vectors as well as between these types and plain 
old Ada arrays?

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 9%]

* cobegin ... coend
@ 2017-07-01  7:11  6% G.B.
  0 siblings, 0 replies; 94+ results
From: G.B. @ 2017-07-01  7:11 UTC (permalink / raw)


A chapter about concurrent processes an older book
introduces the notation
      *cobegin* S1; S2; ...; Sn *coend*.
It is also presenting a procedure as an example. An attempt
at translating it into Ada is given below.

Ignoring the premiss that Ada processes are tasks and
that designing algorithms should therefore not ignore
tasks, is there a known good way of translating the
start of processes from *cobegin*...*coend* style to tasks?
Or from OpenMP to tasks, I should think. (Paraffin only?)

The example procedure Copy copies a sequence of records to
another sequence, emptying the source. Package Sequences is
an instance of Ada.Containers.Doubly_Linked_Lists.

    procedure Get (Item     :    out Copyable;
                   Sequence : in out Sequences.List);

    procedure Put (Item     : in     Copyable;
                   Sequence : in out Sequences.List);

    procedure Copy (F, G : in out Sequences.List)
    is
       S, T      : Copyable;
       Completed : Boolean;
    begin
       if not F.Is_Empty then
          Completed := False;
          Get (S, F);
          loop
             T := S;
             -- cobegin
             Put (T, G);
             if F.Is_Empty then
                Completed := True;
             else
                Get (S, F);
             end if;
             -- coend
             exit when Completed;
          end loop;
       end if;
    end Copy;

The "processes" in the marked section, i.e. Put
and if-statement use disjoint sets of variables.

My first translation has picked the easier part, by having
a local task perform Put (T, G).

    procedure Copy_1 (F, G : in out Sequences.List)
    is
       S, T      : Copyable;
       Completed : Boolean;

       task Assistant is
          entry Put;
       end Assistant;

       task body Assistant is
       begin
          loop
             select accept Put; Put (T, G);
             or terminate;
             end select;
          end loop;
       end Assistant;

    begin
       if not F.Is_Empty then
          Completed := False;
          Get (S, F);
          loop
             T := S;
             -- cobegin
             Assistant.Put;
             if F.Is_Empty then
                Completed := True;
             else
                Get (S, F);
             end if;
             -- coend
             exit when Completed;
          end loop;
       end if;
    end Copy_1;



The second "process" between *cobegin* and *coend* seemed trickier,
as the surrounding control structure depends on the process's result,
i.e., on variable Completed having been set in time. So, the loop
needs to wait for another rendezvous, for example.

Are such things planned for Ada 2X's new parallel features?

^ permalink raw reply	[relevance 6%]

* Ada 2005,Doubly_Linked_List with Controlled parameter
@ 2016-04-05  2:03  7% George J
  0 siblings, 0 replies; 94+ results
From: George J @ 2016-04-05  2:03 UTC (permalink / raw)


Hi all! I'm using Doubly_Linked_List with Controlled param, example here:

   ----------------------------------------------------------------------
   type Info_Record is new Controlled with
      record
         Name:String_Access;
      end record;
   type Info is access all Info_Record'Class;
   overriding procedure Finalize(Self:in out Info_Record);

   package Test_Containers is new Ada.Containers.Doubly_Linked_Lists(Info_Record);
   use Test_Containers;

   Test_List:Test_Containers.List;
   ----------------------------------------------------------------------
   procedure Free_String is new Ada.Unchecked_Deallocation
(Object => String,
 Name   => String_Access);

   overriding procedure Finalize(Self:in out Info_Record) is
   begin
      if  Self.Name/=null then
            Free_String(Self.Name);
      end if;
   end Finalize;

   ----------------------------------------------------------------------
   procedure Test is
   begin
   Test_List.Append(Info_Record'(Controlled with
                                   Name => new String'("Test_Name"));
   end Test;
   ----------------------------------------------------------------------

  Problem is that after calling "Append"->at once starts Finalization proc, so appended pure line. I just use an access parameter after this "Doubly_Linked_List(Info)", and it's ok now,but i think that i'm wrong,cause Finalization doesn't start with Test_List.Clear and when exiting program. So question is "How I can finalize Doubly_Connected_List Controlled parameter correctly?Or I must not use Controlled parameter in this list?".
Thanks!

^ permalink raw reply	[relevance 7%]

* Generalized Iterators
@ 2015-12-29 11:50  5% AdaMagica
  0 siblings, 0 replies; 94+ results
From: AdaMagica @ 2015-12-29 11:50 UTC (permalink / raw)


I'm experiencing problems with generalized iterators. The code below is reduced
to the minimum in order to be compilable and show the problem. Note that the
body of Circularly_Linked_Lists is not given since not needed to produce the
problem.

The code follows strictly the examples given in the Ada 2012 Rationale.
Expecially the function Iterate is defined thus:

  function Iterate (CLL: not null access Circularly_Linked_List)
    return Forward_Iterator'Class;

This produces the compiler message (GNAT GPL 2015)

  for Cursor in List.Iterate loop
ausprobieren.adb:15:21: expect object that implements iterator interface

Note that the aspects Default_Iterator and Iterator_Element are not needed as
long as the loop above uses "in" rather than "of".

If the function Iterate is replaced by (note the place of the attribute Class)

  function Iterate (CLL: not null access Circularly_Linked_List'Class)
    return Forward_Iterator;

the loop works as expected. When I then add the aspects Default_Iterator
and Iterator_Element and try to use the "of" loop, I get

  for Int of List loop
ausprobieren.adb:19:14: expected an access type with designated type "Circularly_Linked_List'Class" defined at circularly_linked_lists.ads:9, instance at line 8
ausprobieren.adb:19:14: found private type "Circularly_Linked_List" defined at circularly_linked_lists.ads:9, instance at line 8
ausprobieren.adb:19:14:   ==> in call to "Iterate" at circularly_linked_lists.ads:32, instance at line 8
ausprobieren.adb:19:14:   ==> in call to "Iterate" at circularly_linked_lists.ads:32, instance at line 8
ausprobieren.adb:19:19: invalid prefix in selected component "I280b"
    Put_Line (Integer'Image (Int));
  end loop;

I can understand this since Iterate has the list as an access parameter,
and the compiler tries to construct the "in" loop from the default iterator.
But also this does not work:

  for Int of List'Access loop

Is this a problem of GNAT or is there anything I just don't see?

Also in Ada.Containers.Doubly_Linked_Lists, Iterate is defined like so with
the Class attribute at the iterator:

   function Iterate (Container : List)
      return List_Iterator_Interfaces.Reversible_Iterator'Class;

Code below:
------------------------
with Ada.Iterator_Interfaces;

generic

  type Element_Type is private;

package Circularly_Linked_Lists is

  type Circularly_Linked_List is tagged private
    with -- Default_Iterator  => Iterate,
         -- Iterator_Element  => Element_Type,
         Variable_Indexing => Acc;

  type Accessor (Elem: not null access Element_Type) is limited null record
    with Implicit_Dereference => Elem;

  type Cursor is private;

  function Has_Element (Position: Cursor) return Boolean;

  function Acc (CLL     : in out Circularly_Linked_List;
                Position: in     Cursor) return Accessor;

  package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element);

  type Forward_Iterator (CLL: not null access Circularly_Linked_List) is new Iterator_Interfaces.Forward_Iterator with null record;

  overriding function First (Object  : Forward_Iterator) return Cursor;
  overriding function Next  (Object  : Forward_Iterator;
                             Position: Cursor          ) return Cursor;

--function Iterate (CLL: not null access Circularly_Linked_List'Class) return Forward_Iterator;
  function Iterate (CLL: not null access Circularly_Linked_List      ) return Forward_Iterator'Class;

private

  type CLL_Ptr is access all Circularly_Linked_List;

  type Cursor is record
    Current: CLL_Ptr;
  end record;

  type Circularly_Linked_List is tagged record
    Next, Prev: CLL_Ptr;
  end record;

end Circularly_Linked_Lists;
with Ada.Text_IO;
use  Ada.Text_IO;

with Circularly_Linked_Lists;

procedure Ausprobieren is

  package Lists is new Circularly_Linked_Lists (Integer);
  use Lists;

  List: aliased Circularly_Linked_List;

begin

  for Cursor in List.Iterate loop
    Put_Line (Integer'Image (List (Cursor)));
  end loop;

end Ausprobieren;


^ permalink raw reply	[relevance 5%]

* Mutating elements of constant list using a container element iterator
@ 2015-08-04 23:56 10% martinbbjerregaard
  0 siblings, 0 replies; 94+ results
From: martinbbjerregaard @ 2015-08-04 23:56 UTC (permalink / raw)


Mutating elements of a constant container in a "for ... of ... loop" is possible with the "standard" container types but not the indefinite or bounded containers:

with Ada.Containers.Doubly_Linked_Lists;
with Ada.Containers.Indefinite_Doubly_Linked_Lists;

procedure Strange_Behavior is
   
   type Test is tagged
      record
         Value : Integer;
      end record;
   
   package Test_Lists is new Ada.Containers.Doubly_Linked_Lists (Element_Type => Test);
   package Test_Indefinite_Lists is new Ada.Containers.Indefinite_Doubly_Linked_Lists (Element_Type => Test);
   
   function Make_List return Test_Lists.List is
   begin
      return Result : Test_Lists.List := Test_Lists.Empty_List do
         for I in 0 .. 100 loop
            Result.Append (Test'(Value => I));
         end loop;
      end return;
   end Make_List;
   
   function Make_Indefinite_List return Test_Indefinite_Lists.List is
   begin
      return Result : Test_Indefinite_Lists.List := Test_Indefinite_Lists.Empty_List do
         for I in 0 .. 100 loop
            Result.Append (Test'(Value => I));
         end loop;
      end return;
   end Make_Indefinite_List;
   
   V1 : constant Test_Lists.List := Make_List;
   V2 : constant Test_Indefinite_Lists.List := Make_Indefinite_List;
   
begin
   
   for Item of V1 loop
      Item.Value := 0; -- no error
   end loop;
   
   for Item of V2 loop
      Item.Value := 0; -- error: "left hand side of assignment must be a variable"
   end loop;
   
end Strange_Behavior;

http://www.ada-auth.org/standards/12rat/html/Rat12-8-3.html says:
"If we write
for E of The_List loop
   ...   -- do something to Element E
end loop;
then we can change the element E unless The_List has been declared as constant."

Is this a bug?


^ permalink raw reply	[relevance 10%]

* Re: container of a container...
    2015-07-31 21:48 11% ` Niklas Holsti
@ 2015-08-01 11:56 11% ` Björn Lundin
  1 sibling, 0 replies; 94+ results
From: Björn Lundin @ 2015-08-01 11:56 UTC (permalink / raw)


On 2015-07-31 23:13, Hedley Rainnie wrote:
> Is it possible to code that? I am coming from the C++ STL world where, it  relatively easy to put that together. (a vector of lists as an example).
> 
> There are many wonderful examples for Ada containers (stacks etc). But I have not seen any container[container[...]..] examples.
> 
> Being new to Ada, I am sure I have missed something obvious...
> 
> 


--Below creates a map, keyed on 2 character length strings
--and hold a list of integers;
--it also prints the items of each list in the two map-entries

with Ada.Containers.Doubly_Linked_Lists;
with Ada.Containers.Hashed_Maps;
with Ada.Strings;
with Ada.Strings.Hash;
with Text_Io;

procedure Lists is



  package Integer_Pack is new Ada.Containers.Doubly_Linked_Lists(integer);

  subtype String_Key_Type is String(1..2);

  package List_Maps is new Ada.Containers.Hashed_Maps (
         String_Key_Type,
         Integer_Pack.List,
         Ada.Strings.Hash,
         "=",
         Integer_Pack."=");

   Map         : List_Maps.Map ;
   Integer_List : Integer_Pack.List;
begin


  for i in 1 .. 20 loop
    Integer_List.Append(i);
  end loop;


  Map.Insert("12", Integer_List);

  Integer_List.Clear;

  for i in 21 .. 40 loop
    Integer_List.Append(i);
  end loop;

  Map.Insert("11", Integer_List);


  for L of map("11") loop
     Text_Io.Put_Line(L'img);
  end loop;

  for L of map("12") loop
     Text_Io.Put_Line(L'img);
  end loop;

end Lists;




-- 
--
Björn

^ permalink raw reply	[relevance 11%]

* Re: container of a container...
  @ 2015-07-31 21:48 11% ` Niklas Holsti
  2015-08-01 11:56 11% ` Björn Lundin
  1 sibling, 0 replies; 94+ results
From: Niklas Holsti @ 2015-07-31 21:48 UTC (permalink / raw)


On 15-08-01 00:13 , Hedley Rainnie wrote:
> Is it possible to code that? I am coming from the C++ STL world
> where, it  relatively easy to put that together. (a vector of lists
> as an example).
>
> There are many wonderful examples for Ada containers (stacks etc).
> But I have not seen any container[container[...]..] examples.
>
> Being new to Ada, I am sure I have missed something obvious...


Example of a vector of lists of characters:

with Ada.Containers.Vectors;
with Ada.Containers.Doubly_Linked_Lists;

procedure Vec_List
is

    package Char_Lists is new Ada.Containers.Doubly_Linked_Lists (
       Element_Type => Character);

    package Char_List_Vectors is new Ada.Containers.Vectors (
       Index_Type   => Positive,
       Element_Type => Char_Lists.List,
       "="          => Char_Lists."=");

    Vec : Char_List_Vectors.Vector;

    ABC : Char_Lists.List;

begin

    ABC.Append ('A');
    ABC.Append ('B');
    ABC.Append ('C');

    Vec.Replace_Element (3, ABC);

end Vec_List;


-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


^ permalink raw reply	[relevance 11%]

* Re: If not Ada, what else...
  @ 2015-07-29 18:52  8%                                         ` Björn Lundin
  0 siblings, 0 replies; 94+ results
From: Björn Lundin @ 2015-07-29 18:52 UTC (permalink / raw)


On 2015-07-29 20:27, Paul Rubin wrote:
> Björn Lundin <b.f.lundin@gmail.com> writes:
>> See Ada.Containers.*
> 
> Will look there, but those kinds of containers are more useful with GC.

I think you are missing the point.
Many things in Ada is done without allocating with 'new'
And things that are, if OO, may inherit from
Ada.Finalized, which gives a call to the objects'
'Finalize' method where deallcation - if necessary - can be done.
So, the user does not fiddle with new/free.



  declare
  package Stuff_Pkg is new Ada.Containers.Doubly_Linked_Lists(Stuff_Type);
  Stuff_data : Stuff_type;
  Stuff_List : Stuff_Pkg.List
  begin
   for i in 1 ..100 loop
     Stuff_list.Append(Stuff_data):
   end loop;

   -- use stuff_list here

  end;

 --no mem leak here
> 
>> How is Haskell doing in Ada territory, like concurrency etc ?
> 
> It's partly on the implementation, but GHC's concurrency is far superior
> to GNAT's in my opinion.  GNAT uses Posix threads while GHC supports
> lightweight threads with parallel garbage collection.  It can handle
> millions of concurrent threads on a large server:
> 
>   http://haskell.cs.yale.edu/wp-content/uploads/2013/08/hask035-voellmy.pdf
> 
> GHC also supports software transactional memory (STM), that let threads
> composably share mutable data without the traditional hazards of lock
> inversion etc.  Haskell's type system statically verifies that STM
> operations aren't improperly mixed with I/O that could wedge the runtime:
> 
>   http://book.realworldhaskell.org/read/software-transactional-memory.html
> 
> GHC also supports various kinds of deterministic parallelism, like the
> "par" operator that lets you very simply annotate that two operations
> can be done in parallel (on separate cpu cores):
> 
>   https://donsbot.wordpress.com/2007/11/29/use-those-extra-cores-and-beat-c-today-parallel-haskell-redux/
> 
> The cool thing about this is it doesn't affect the datatypes in the
> program, and if you use it improperly, your program might run slower
> instead of faster, but it will still find the right answers.
> 
> There are also data parallelism libraries that will let you spin array
> computations off to SIMD units or GPU's, but Ada probably has similar
> libraries.
> 
> There is an online book about parallel and concurrent programming in
> Haskell (scroll down for the TOC):
> 
>   http://chimera.labs.oreilly.com/books/1230000000929/index.html
> 
> ================
> 
> Where Ada beats Haskell is in deterministic timing and memory footprint.
> SPARK has ways to verify that an Ada function can't possibly throw an
> exception.  That's difficult in Haskell, because programs constantly use
> the memory allocator, and there can also be unpredictable GC pauses at
> any time in the program.  Ada can also compile to small cpu targets
> because of its small or nonexistent runtime system.
> 
> So I'd see the archetypal Ada application as a critical embedded system
> like a jet engine controller, while the archetypal Haskell application
> is something like a compiler or internet server that must not give wrong
> answers, but where a pause in execution (or even an OOM crash followed
> by a failover or workaround) is annoying but not disastrous.
> 

Interesting reading

-- 
--
Björn

^ permalink raw reply	[relevance 8%]

* Re: Interesting containers problem.
  @ 2015-04-20 23:39  8%       ` Randy Brukardt
  0 siblings, 0 replies; 94+ results
From: Randy Brukardt @ 2015-04-20 23:39 UTC (permalink / raw)


"Shark8" <onewingedshark@gmail.com> wrote in message 
news:ced95bb5-0bb3-43ee-8d2c-212ea020fd10@googlegroups.com...
> On Friday, April 17, 2015 at 2:45:07 PM UTC-6, Randy Brukardt wrote:
...
> Ok, I see how a multiway tree maps the structure of nesting scopes... but 
> maybe I'm
>being obtuse here, because I don't see how to access them because there's 
>no 'key'
>type. (Maybe a bit of code would help here.)

The keys are into a map of which each element is a list of tree nodes (that 
is, tree cursors) that have the given identifier. Thus, you have:

    package Symbol_Tree is new Ada.Containers.Indefinite_Multiway_Trees 
(Element_Type => Symbol_Root'Class);

    package Symbol_List is new Ada.Containers.Doubly_Linked_Lists 
(Element_Type => Symbol_Tree.Cursor);

    package Identifier_Map is new Ada.Containers.Indefinite_Hashed_Map 
(Element_Type => Symbol_List.List,
         Key_Type => String, -- Probably really a UTF8_String,
         Hash => ..., Equivalent_Keys => ...);

  I'm too lazy to look up the proper names of the routines to use for the 
Hash function and the case insensitive equivalency; it's not relevant to the 
routine anyway.

> The way I see it is that the structure we want is essentially a map where 
> an identifier
>is keyed to one of two things: (a) a variable_data, or (b) another 
>scope-map. -- This
>would allow/model nesting.

But that doesn't help much (for Ada). In any case, you start with the entire 
list of declarations with the appropriate identifier and prune out 
inappropriate kinds of declarations (wrong scope, etc.). The problem is that 
declarations such as overloaded subprograms don't hide each other unless 
they're homographs (that is, have the same profile). The identifier alone 
doesn't tell you much; you have to collect all of the declarations that 
might be visible.

What you are talking about would help in an antique language that doesn't 
support any overloading, but I would hope that people in this group are 
beyond that. :-) If anything, Ada doesn't have enough overloading (too much 
reliance on scopes, something that should have almost no bearing on 
visibility).

Keep in mind that there are many possible queries into a symboltable, and 
it's never going to be viable to make it easy for all of them. For Ada, you 
need to look up by identifier, by visibility, by primitive for a given type, 
and so on. It's not sensible to make it easy to do all of those things.

                                                          Randy.







^ permalink raw reply	[relevance 8%]

* Re: Strange error
  @ 2015-01-24  0:47  8%     ` Bob Duff
  0 siblings, 0 replies; 94+ results
From: Bob Duff @ 2015-01-24  0:47 UTC (permalink / raw)


Laurent <daemon2@internet.lu> writes:

> Quite obvious could have found that myself by thinking/searching a bit more.
>
> How do you professionals prevent such stupid errors? I am just a noob and
> playing a bit around so it has no impact on anything.

One way is to use Ada.Containers.Doubly_Linked_Lists.  But that won't
work for you, because you're not trying to use doubly-linked lists,
you're trying to learn how to implement them.  Which is something
programmers should know how to do.

So draw a doubly-linked list on paper, with circles and arrows.
Go through each procedure and "execute" it by hand, erasing the
arrows and drawing new ones.  Take care to execute what you wrote,
not what you meant to write.  Bugs like the one mentioned will
usually become obvious.

- Bob


^ permalink raw reply	[relevance 8%]

* Re: How to use read-only variables?
  @ 2015-01-04 12:56  7% ` hreba
  0 siblings, 0 replies; 94+ results
From: hreba @ 2015-01-04 12:56 UTC (permalink / raw)


On 01/03/2015 10:58 PM, hreba wrote:
> My Ada book says that 'access const' types serve for readonly
> variables but I am not sure whether I grasped the idea.
>
> I want a readonly variable 'n' as component of a record 'R'. The
> variable which is accessed by 'n', let's call it 'nv' must be hidden,
> otherwise the client could change it.
>
> Consequently 'R' must be extensible, that is tagged. It makes no sense
> to use the base class alone (without something for 'n' to point to),
> so it must be abstract. As the pointer-target relation wouldn't be
> conserved in a simple assignment, the record must be limited. This
> leads to
>
>     type R is abstract tagged limited record
>        n:    access constant Integer;
>     end record;
>
>     type Rv is new R with private;
>
> private
>
>     type Rv is new R with record
>        nv:    aliased Integer;
>     end record;
>
> The value of 'n' would be defined in an initialization procedure:
>
>     procedure Init (rec: in out Rv) is
>     begin
>        rec.n:= rec.nv'Access;
>     end Init;
>
> This however gives me an error message:
>
>     non-local pointer cannot point to local object
>
> Now I am really confused:
>
>   - Are readonly variables really handled this way, typically?
>   - How can rec.nv be local and rec.n not?
>   - How would you write the correct initialization procedure?
>
> All this seems pretty complicated to somebody used to Oberon, where
> all this would be simply written as
>
> TYPE
>     R* = RECORD
>             n-: INTEGER;
>          END;
>

I am responding to my own post in order not to repeat myself in 
individual answers.

First of all: thanks for your help.

Second, I thought the meaning of "read-only" was clear, but perhaps it 
isn't. What I meant is what Brad expressed as "read only from the client 
perspective but modifiable locally".

Third, looking at the answer of Shark8 which solves the problem using 
"access const", I guess using a function returning the value of a hidden 
variable would be a much simpler solution. An example of a read-only 
variable would be the number of elements in a linked list. Within the 
defining package it is changed whenever the user adds or removes an 
element, you want the user to read it, but by no means you want to give 
him write access to it. I guess I understand now why 'Length' in 
Ada.Containers.Doubly_Linked_Lists is a function and no read-only variable.

Fourth, in what practical cases do you really use 'access const' for 
read-only variables; I thought my case a pretty typical one?

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[relevance 7%]

* Re: Select then abort can fail to abort the abortable part
  2014-11-21  8:37  0%     ` Dmitry A. Kazakov
@ 2014-11-21 15:26  8%       ` Jean François Martinez
  0 siblings, 0 replies; 94+ results
From: Jean François Martinez @ 2014-11-21 15:26 UTC (permalink / raw)


On Friday, November 21, 2014 9:37:33 AM UTC+1, Dmitry A. Kazakov wrote:

> I don't see how being controlled (or tagged) were related. Primitive
> operations are not abort-deferred except for Initialize and Finalize (and
> only under certain conditions). RM 9.8.
> 

Actually while playing with asynchronous select I got an exception from  Ada.Containers.Doubly_Linked_Lists telling me I was trying to abort at the wrong time and about a controlled object.

I think somewhere in the code there is 

procedure Must_be_atomic is
  A: My_controlled_type;
begin

end My_Atomic

and the Finalize of My_Controled_Type raising an exception
---
Jean-Frannçois Martinez


^ permalink raw reply	[relevance 8%]

* Re: Select then abort can fail to abort the abortable part
  2014-11-20 22:19  0%   ` Jean François Martinez
@ 2014-11-21  8:37  0%     ` Dmitry A. Kazakov
  2014-11-21 15:26  8%       ` Jean François Martinez
  0 siblings, 1 reply; 94+ results
From: Dmitry A. Kazakov @ 2014-11-21  8:37 UTC (permalink / raw)


On 20 Nov 2014 22:19:30 GMT, Jean François Martinez wrote:

> On Thu, 20 Nov 2014 22:35:27 +0100, Dmitry A. Kazakov wrote:
> 
>> You certainly should not abort any code changing dynamically allocated
>> structures. I don't know the implementation of
>> Ada.Containers.Doubly_Linked_Lists, but it is not protected against
>> abort in the middle of changing list links, you may get garbage in the
>> result.
> 
> Actually Lists are Controlled Objects and an exception is raised if 
> you try to abort a task at the time it is trying to modify the List

I don't see how being controlled (or tagged) were related. Primitive
operations are not abort-deferred except for Initialize and Finalize (and
only under certain conditions). RM 9.8.

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

^ permalink raw reply	[relevance 0%]

* Re: Select then abort can fail to abort the abortable part
  2014-11-20 21:35  8% ` Dmitry A. Kazakov
@ 2014-11-20 22:19  0%   ` Jean François Martinez
  2014-11-21  8:37  0%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 94+ results
From: Jean François Martinez @ 2014-11-20 22:19 UTC (permalink / raw)


On Thu, 20 Nov 2014 22:35:27 +0100, Dmitry A. Kazakov wrote:


> 
> You certainly should not abort any code changing dynamically allocated
> structures. I don't know the implementation of
> Ada.Containers.Doubly_Linked_Lists, but it is not protected against
> abort in the middle of changing list links, you may get garbage in the
> result.
> 

Actually Lists are Controlled Objects and an exception is raised if 
you try to abort a task at the time it is trying to modify the List

> You should almost never use the asynchronous transfer of control. A
> clean method of aborting a lengthy computation is by inserting
> inspection points within loops and raising an exception when abort was
> requested or time was expired.

I was just kicking the tires of something (select then abort) I have 
never used.  

---
Jean-François Martinez

^ permalink raw reply	[relevance 0%]

* Re: Select then abort can fail to abort the abortable part
  2014-11-20 21:08  5% Select then abort can fail to abort the abortable part Jean François Martinez
@ 2014-11-20 21:35  8% ` Dmitry A. Kazakov
  2014-11-20 22:19  0%   ` Jean François Martinez
  0 siblings, 1 reply; 94+ results
From: Dmitry A. Kazakov @ 2014-11-20 21:35 UTC (permalink / raw)


On 20 Nov 2014 21:08:50 GMT, Jean François Martinez wrote:

> Context:  Gnat x86_64 on Linux
> 
> 
> Let's have that simple loop
> 
> for Ind in 1..6
> loop
>     Start:=Clock;
>     select
>         delay Ind * 10.0
>     then abort 
>        Ultimate_Prime;
>     end select; 
>     My_Duration:= Clock - Start;
> end loop;
> 
> Ultimate_Prime is function containing a nearly infinite loop trying to 
> find prime numbers.  
> 
> First version stores primes found.  This mandates a linked list but that 
> would create an unacceptable overhead so I use big chunks
> 
>      type Big_Array is array (Positive range 1..100_000) of Long_Mod;
>      type Chunk is record
>           Position: Positive  range Big_Array'Range;
>           Payload: Big_Array;
>      end record;
>      type T_Ptr_Chunk is access  T;
> 
>      package P_List_Chunks is
>        new Ada.Containers.Doubly_Linked_Lists(T_Ptr_Chunk);

You certainly should not abort any code changing dynamically allocated
structures. I don't know the implementation of
Ada.Containers.Doubly_Linked_Lists, but it is not protected against abort
in the middle of changing list links, you may get garbage in the result.

You should almost never use the asynchronous transfer of control. A clean
method of aborting a lengthy computation is by inserting inspection points
within loops and raising an exception when abort was requested or time was
expired.

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

^ permalink raw reply	[relevance 8%]

* Select then abort can fail to abort the abortable part
@ 2014-11-20 21:08  5% Jean François Martinez
  2014-11-20 21:35  8% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 94+ results
From: Jean François Martinez @ 2014-11-20 21:08 UTC (permalink / raw)


Context:  Gnat x86_64 on Linux


Let's have that simple loop

for Ind in 1..6
loop
    Start:=Clock;
    select
        delay Ind * 10.0
    then abort 
       Ultimate_Prime;
    end select; 
    My_Duration:= Clock - Start;
end loop;

Ultimate_Prime is function containing a nearly infinite loop trying to 
find prime numbers.  

First version stores primes found.  This mandates a linked list but that 
would create an unacceptable overhead so I use big chunks

     type Big_Array is array (Positive range 1..100_000) of Long_Mod;
     type Chunk is record
          Position: Positive  range Big_Array'Range;
          Payload: Big_Array;
     end record;
     type T_Ptr_Chunk is access  T;

     package P_List_Chunks is
       new Ada.Containers.Doubly_Linked_Lists(T_Ptr_Chunk);
     use P_List_Chunks;

     List_Chunks: List;


So this first version is "dumb": it tries every odd number until 
Divisor * Divisor > Candidate.  If it is a prime it is stored in the 
Payload array though an access variable ie _without_ even looking at the 
List.  The List is only accessed for concatenating a new Chunk.
Now when I run it I notice that the select then abort can take over 1 
second or even two seconds more than the delay and the number of
Primes found is ever a multiple of 100_000 ie the function was only 
aborted when it entered code provided by AdaCore in order to allocate a 
new Chunk and to add a new element to the List.

The second version is "smart". It only tries to divide by prime numbers.  
This means we have to use the numbers previously stored in our list so

for An_Element in List_Chunks
loop 
    for Ind in 1..Position
    loop

In this version we are constantly traversing List_Chunks and using 
Adacore's code.  Here the function is aborted very close after the 
expiration of the delay (from memory 0.05 at most after expiration) and 
the number of prime numbers found is not a multiple of 100_000.

Third version is tries very odd number as divisor but stores only the 
last prime found.  Ie no lists, no nothing.  Just user code, nothing from 
the run time or AdaCore's libraries.   In this version the delay expires 
but the there is no abort _at all_.  Function will run until it leaves 
voluntarily in, according my estimations, something like five hundred 
thousand years.

Is this incorrect behavior?

---
Jean-François Martinez

^ permalink raw reply	[relevance 5%]

* Re: Queue implementation in Ada
  2014-10-28 18:29  0%     ` Jeffrey Carter
@ 2014-10-28 19:25  0%       ` Simon Wright
  0 siblings, 0 replies; 94+ results
From: Simon Wright @ 2014-10-28 19:25 UTC (permalink / raw)


Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:

> On 10/28/2014 03:00 AM, Simon Wright wrote:
>> Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:
>> 
>>> If you want unsynchronized queues, you could build your own, possibly
>>> using Ada.Containers.Doubly_Linked_Lists (ARM A.18.3).
>> 
>> I used Vectors, ARM A.18.2. Not sure why one would choose one over the
>> other?
>
> In the sense that both are random-access sequences, with essentially
> the same interface, there is none. One could build either as a wrapper
> around the other.
>
> Clearly any difference must be in the implementation. Given that one
> is named Doubly_Linked_Lists and the other adds index-based access,
> it's reasonable to think that the former is expected to be implemented
> as a linked list and the latter as an array. Since a queue experiences
> frequent additions to the tail and frequent deletions from the head,
> the linked list seems appropriate.

Good point.

I've been put off Doubly_Linked_Lists because I would usually have been
quite happy with singly linked lists. But really, what difference does
it make if all you're doing is implementing a Queue!

^ permalink raw reply	[relevance 0%]

* Re: Queue implementation in Ada
  2014-10-28 10:00  0%   ` Simon Wright
@ 2014-10-28 18:29  0%     ` Jeffrey Carter
  2014-10-28 19:25  0%       ` Simon Wright
  0 siblings, 1 reply; 94+ results
From: Jeffrey Carter @ 2014-10-28 18:29 UTC (permalink / raw)


On 10/28/2014 03:00 AM, Simon Wright wrote:
> Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:
> 
>> If you want unsynchronized queues, you could build your own, possibly
>> using Ada.Containers.Doubly_Linked_Lists (ARM A.18.3).
> 
> I used Vectors, ARM A.18.2. Not sure why one would choose one over the
> other?

In the sense that both are random-access sequences, with essentially the same
interface, there is none. One could build either as a wrapper around the other.

Clearly any difference must be in the implementation. Given that one is named
Doubly_Linked_Lists and the other adds index-based access, it's reasonable to
think that the former is expected to be implemented as a linked list and the
latter as an array. Since a queue experiences frequent additions to the tail and
frequent deletions from the head, the linked list seems appropriate.

-- 
Jeff Carter
"My mind is a raging torrent, flooded with rivulets of
thought, cascading into a waterfall of creative alternatives."
Blazing Saddles
89


^ permalink raw reply	[relevance 0%]

* Re: Queue implementation in Ada
  2014-10-28  3:30  8% ` Jeffrey Carter
@ 2014-10-28 10:00  0%   ` Simon Wright
  2014-10-28 18:29  0%     ` Jeffrey Carter
  0 siblings, 1 reply; 94+ results
From: Simon Wright @ 2014-10-28 10:00 UTC (permalink / raw)


Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:

> If you want unsynchronized queues, you could build your own, possibly
> using Ada.Containers.Doubly_Linked_Lists (ARM A.18.3).

I used Vectors, ARM A.18.2. Not sure why one would choose one over the
other?


^ permalink raw reply	[relevance 0%]

* Re: Queue implementation in Ada
  @ 2014-10-28  3:30  8% ` Jeffrey Carter
  2014-10-28 10:00  0%   ` Simon Wright
  0 siblings, 1 reply; 94+ results
From: Jeffrey Carter @ 2014-10-28  3:30 UTC (permalink / raw)


On 10/27/2014 07:01 PM, compguy45@gmail.com wrote:
> Is there queue fifo implemented in ada? I saw this example but not sure where he is fetting fifo package
> http://rosettacode.org/wiki/Queue/Usage

Ada has synchronized queues; see ARM A.18.27-31

http://www.adaic.org/resources/add_content/standards/12rm/html/RM-A-18-27.html

If you want unsynchronized queues, you could build your own, possibly using
Ada.Containers.Doubly_Linked_Lists (ARM A.18.3). Or you could download an
existing library that implements them, such as the PragmAda Reusable Components

http://pragmada.x10hosting.com/pragmarc.htm

-- 
Jeff Carter
"You me on the head hitted."
Never Give a Sucker an Even Break
108


^ permalink raw reply	[relevance 8%]

* Re: Curiosity in generic package instantiation
  2014-08-19 23:16  7% ` Adam Beneschan
@ 2014-08-21 22:39  0%   ` Randy Brukardt
  0 siblings, 0 replies; 94+ results
From: Randy Brukardt @ 2014-08-21 22:39 UTC (permalink / raw)


"Adam Beneschan" <adambeneschan@gmail.com> wrote in message 
news:f9998a20-46fd-492a-b8a3-02105f728e82@googlegroups.com...
...
>An implementation can do either.  Suppose you instantiate 
>Ada.Containers.Doubly_Linked_Lists
> with multiple types in the same program:
>
>    package Example_Pkg is new 
> Ada.Containers.Doubly_Linked_List(Example_Type);
>    package Another_Pkg is new 
> Ada.Containers.Doubly_Linked_List(Another_Type);
>    package A_Third_Pkg is new Ada.Containers.Doubly_Linked_List(Type_3);
>
> If you compile with GNAT, you'll get three copies of the 
> Doubly_Linked_List code, with
> each copy set up to work on a different type.  If you compile with Janus 
> Ada, you will get
> only one copy of the code.  I'm not entirely sure what the code looks 
> like, but probably
> when the subprograms in the instantiation are called, they will be given a 
> parameter that
> contains some information needed about each type, such as the size of the 
> type, so that
> the code in the instantiation will know what to do when copying objects of 
> the type
> around.  I'm assuming this approach takes less code space but performs a 
> little slower.

The run-time cost (if any) depends mainly on the type of formal parameter. 
For formal private types, the code is almost the same as it would have been 
anyway (assignments and initializations being done about the same as they 
would have anyway, especially if the actual type is some sort of record). 
(There's a small cost for declared objects as they need an extra level of 
indirection.) Similarly, the various formal scalar types are not much 
impacted. OTOH, some of the lesser used formal parameters have a larger cost 
(in code and space).

Our original plan was to use automatic inlining to reduce these costs (it's 
a lot easier to unshare code that was compiled to be shared than it is to 
share code that was compiled separately -- we did the latter for our Z-80 
CP/M compilers, but it didn't work at all on the 8086 processors). We never 
got around to implementing that (in part because it required larger hosts 
than were common back in the day, and now there is a long list of other 
things that are more important), so it's hard to say how well that would 
have worked.

                                                 Randy.


^ permalink raw reply	[relevance 0%]

* Re: Curiosity in generic package instantiation
  2014-08-19 22:26 10% Curiosity in generic package instantiation GianLuigi Piacentini
  2014-08-19 23:16  7% ` Adam Beneschan
@ 2014-08-20  7:18  0% ` Björn Lundin
  1 sibling, 0 replies; 94+ results
From: Björn Lundin @ 2014-08-20  7:18 UTC (permalink / raw)


On 2014-08-20 00:26, GianLuigi Piacentini wrote:
> if I understand well, this means that the Ada.Containers.Doubly_Linked_Lists 
> package is instantiated using Example_Type, and the instantiated list name 
> is Example_Pkg.List.

Almost, but not quite.
The list is called 'List' and is of _type_ Example_Pkg.List

I am one of hem who prefers tucking '_Type' in the end of type names
just to avoid this sort of confusion.
So if I wrote the package, the type would have been called

Example_Pkg.List_Type


--
Björn

^ permalink raw reply	[relevance 0%]

* Re: Curiosity in generic package instantiation
  2014-08-19 22:26 10% Curiosity in generic package instantiation GianLuigi Piacentini
@ 2014-08-19 23:16  7% ` Adam Beneschan
  2014-08-21 22:39  0%   ` Randy Brukardt
  2014-08-20  7:18  0% ` Björn Lundin
  1 sibling, 1 reply; 94+ results
From: Adam Beneschan @ 2014-08-19 23:16 UTC (permalink / raw)


On Tuesday, August 19, 2014 3:26:01 PM UTC-7, GianLuigi Piacentini wrote:
> Hi all,
> 
> pardon if using not the exact terminology (too old to learn ADA intricacies, 
> whish had done it back in the '80-'90 when I was active programmer, but then 
> in Italy buzzword was c/c++ m$oft version, and VB), I noticed the following 
> excerpt in a previous thread:
> 
> ...
> 
> procedure Test_List is
>     type Example_Type is record
>       A :Integer := 0;
>       B: Integer := 0;
>     end record;
> 
> ...
> 
>   declare
>     Data : Example_Type;
>     package Example_Pkg is new
> Ada.Containers.Doubly_Linked_Lists(Example_Type);
>     List : Example_Pkg.List;
> 
> if I understand well, this means that the Ada.Containers.Doubly_Linked_Lists 
> package is instantiated using Example_Type, and the instantiated list name 
> is Example_Pkg.List.
> 
> Is this done by text substitution at source/intermediate code level 
> (something like the C preprocessor), albeit in an user-transparent (=better) 
> way, or is it obtained by some property of the list elements, able to store 
> whatever is thrown at them, even elements of different type in the same 
> list?
> 
> My 1st guess looking at the code is sort of compiler-integrated 
> preprocessing.
> 
> Just curious.

An implementation can do either.  Suppose you instantiate Ada.Containers.Doubly_Linked_Lists with multiple types in the same program:

    package Example_Pkg is new Ada.Containers.Doubly_Linked_List(Example_Type);
    package Another_Pkg is new Ada.Containers.Doubly_Linked_List(Another_Type);
    package A_Third_Pkg is new Ada.Containers.Doubly_Linked_List(Type_3);

If you compile with GNAT, you'll get three copies of the Doubly_Linked_List code, with each copy set up to work on a different type.  If you compile with Janus Ada, you will get only one copy of the code.  I'm not entirely sure what the code looks like, but probably when the subprograms in the instantiation are called, they will be given a parameter that contains some information needed about each type, such as the size of the type, so that the code in the instantiation will know what to do when copying objects of the type around.  I'm assuming this approach takes less code space but performs a little slower.

The language is designed to support both approaches, and the designers are careful to make sure that both approaches are possible when new language features are added.

The language rules about generic make it so that instantiating a generic is *almost* the same as text substitution, but not quite.  The names and operators in generic code normally mean what they mean when the generic is *compiled*, not when it's instantiated (with some exceptions).  So if you say

    generic
        type FLOAT_TYPE is digits <>;  -- generic formal floating-point type
    package Some_Package is ...

and in the body, you use X + Y on two FLOAT_TYPE's, you will always get the standard meaning of "+" even if you redefine "+" to mean something else on some user-defined floating-point type (a bad idea anyway) and instantiate your package with that type.  If it were a straight text substitution, you'd get the redefined "+", but that isn't how Ada works.  The actual rules are complicated and there are some nuances, though.  But it shouldn't be an issue, until you start writing more complex generics.

                                -- Adam


^ permalink raw reply	[relevance 7%]

* Curiosity in generic package instantiation
@ 2014-08-19 22:26 10% GianLuigi Piacentini
  2014-08-19 23:16  7% ` Adam Beneschan
  2014-08-20  7:18  0% ` Björn Lundin
  0 siblings, 2 replies; 94+ results
From: GianLuigi Piacentini @ 2014-08-19 22:26 UTC (permalink / raw)


Hi all,

pardon if using not the exact terminology (too old to learn ADA intricacies, 
whish had done it back in the '80-'90 when I was active programmer, but then 
in Italy buzzword was c/c++ m$oft version, and VB), I noticed the following 
excerpt in a previous thread:

...
procedure Test_List is
    type Example_Type is record
      A :Integer := 0;
      B: Integer := 0;
    end record;

...

  declare
    Data : Example_Type;
    package Example_Pkg is new
Ada.Containers.Doubly_Linked_Lists(Example_Type);
    List : Example_Pkg.List;

if I understand well, this means that the Ada.Containers.Doubly_Linked_Lists 
package is instantiated using Example_Type, and the instantiated list name 
is Example_Pkg.List.

Is this done by text substitution at source/intermediate code level 
(something like the C preprocessor), albeit in an user-transparent (=better) 
way, or is it obtained by some property of the list elements, able to store 
whatever is thrown at them, even elements of different type in the same 
list?

My 1st guess looking at the code is sort of compiler-integrated 
preprocessing.

Just curious.

Thanks in advance.

Gigi


^ permalink raw reply	[relevance 10%]

* Re: how to delete from Ada.Containers.Doubly_Linked_Lists
  2014-08-18 19:57  9% ` Jeffrey Carter
@ 2014-08-19  8:56 10%   ` Björn Lundin
  0 siblings, 0 replies; 94+ results
From: Björn Lundin @ 2014-08-19  8:56 UTC (permalink / raw)


On 2014-08-18 21:57, Jeffrey Carter wrote:
> On 08/18/2014 11:51 AM, Björn Lundin wrote:

>> How should a nice solution look like ?
> 
> You probably ought to read about "tampering with cursors" in the ARM (A.18.3).
> In your case, iterating over the list needs the list to remain unchanged until
> iteration finishes. Deleting during iteration would violate this.

Hmm, yes I see that now.

> This restriction is intended for safety, and sometimes seems onerous.

That was my suspicion

> I've had
> to iterate over one data structure, storing cursors in another data structure,
> then iterate over the 2nd data structure to delete using the stored cursors.

Yes, basically what my last sample did - saving the cursor 'c' into
'C_Save' and delete outside the loop. That is what I thought was
inelegant/clumpsy

> You can delete during iteration if you don't invoke an Iterate subprogram:

Still a bit inelegant, but thanks for the example.
It is way better that mine.


/Björn






^ permalink raw reply	[relevance 10%]

* Re: how to delete from Ada.Containers.Doubly_Linked_Lists
  2014-08-18 18:51 18% how to delete from Ada.Containers.Doubly_Linked_Lists Björn Lundin
@ 2014-08-18 19:57  9% ` Jeffrey Carter
  2014-08-19  8:56 10%   ` Björn Lundin
  0 siblings, 1 reply; 94+ results
From: Jeffrey Carter @ 2014-08-18 19:57 UTC (permalink / raw)


On 08/18/2014 11:51 AM, Björn Lundin wrote:
> 
> 
> I've got a sample below,
> but I fell it is clumpsy.
> How should a nice solution look like ?

You probably ought to read about "tampering with cursors" in the ARM (A.18.3).
In your case, iterating over the list needs the list to remain unchanged until
iteration finishes. Deleting during iteration would violate this.

This restriction is intended for safety, and sometimes seems onerous. I've had
to iterate over one data structure, storing cursors in another data structure,
then iterate over the 2nd data structure to delete using the stored cursors.

You can delete during iteration if you don't invoke an Iterate subprogram:

   declare
      C    : Example_Pkg.Cursor := List.First;
      Next : Example_Pkg.Cursor;

      use type Example_Pkg.Cursor;
   begin
      loop
         exit when C = Example_Pkg.No_Element;

         declare
            I : constant Example_Type := Example_Pkg.Element (C);
         begin
            if I.A /= 15 then
               Example_Pkg.Next (Position => C);
            else
               Next := Example_Pkg.Next (C);
               List.Delete (Position => C);
               C := Next;
            end if;
         end ;
      end loop;
   end;

-- 
Jeff Carter
"You a big nose have it."
Never Give a Sucker an Even Break
107

^ permalink raw reply	[relevance 9%]

* how to delete from Ada.Containers.Doubly_Linked_Lists
@ 2014-08-18 18:51 18% Björn Lundin
  2014-08-18 19:57  9% ` Jeffrey Carter
  0 siblings, 1 reply; 94+ results
From: Björn Lundin @ 2014-08-18 18:51 UTC (permalink / raw)



Hi,
I try to get aquinted with Ada.Containers.Doubly_Linked_Lists,
which I feel may replace a homebrew list class we
use at work.

Especailly the 'for of' notation
seems nice to have.

But How do I delete an item in the list
while looping it?

I've got a sample below,
but I fell it is clumpsy.
How should a nice solution look like ?

/Björn


with Text_Io;
with Ada.Containers.Doubly_Linked_Lists;

procedure Test_List is
    type Example_Type is record
      A :Integer := 0;
      B: Integer := 0;
    end record;

    procedure To_String(E : Example_Type) is
    begin
      Text_io.Put_Line(E.A'Img & E.B'Img);
    end To_String;

begin

  Text_io.Put_Line("start Ada.Containers.Doubly_Linked_Lists; ");

  declare
    Data : Example_Type;
    package Example_Pkg is new
Ada.Containers.Doubly_Linked_Lists(Example_Type);
    List : Example_Pkg.List;
  begin

    Text_io.Put_Line("insert 5 elements at tail, ");
    for i in 1..5 loop
      Data := (A => i, B => 2 * i);
      List.Append(Data);
    end loop;

    for i of List loop
      To_String(i);
    end loop;

    Text_io.Put_Line("Update in place");

    for i of List loop
      I.A := 5*I.A;
      I.B := 50*I.B;
    end loop;

    for i of List loop
      To_String(i);
    end loop;

    Text_io.Put_Line("delete if I.a = 15");

    for c in List.Iterate loop
      declare
        i : Example_Type := Example_Pkg.Element(C);
      begin
        if I.A = 15 then
           List.Delete(C);      <-- program_error raised
        end if;
      end ;
    end loop;

    --works but clumplsy

    declare
      C_Save : Example_Pkg.Cursor;
    begin
      for c in List.Iterate loop
        declare
          i : Example_Type := Example_Pkg.Element(C);
        begin
          if I.A = 15 then
            C_Save := C;
            exit;
          end if;
        end ;
      end loop;
      List.Delete(C_Save);
    end;

    for i of List loop
      To_String(i);
    end loop;
    Text_io.Put_Line("done");
  end;
end Test_List;


sample run:

insert 5 elements at tail,
 1 2
 2 4
 3 6
 4 8
 5 10
Update in place
 5 100
 10 200
 15 300
 20 400
 25 500
delete if I.a = 15

Execution terminated by unhandled exception
Exception name: PROGRAM_ERROR
Message: attempt to tamper with cursors (list is busy)



^ permalink raw reply	[relevance 18%]

* Re: Problem with generic linked list package
  @ 2014-08-11  5:13 10%                                   ` Jeffrey Carter
  0 siblings, 0 replies; 94+ results
From: Jeffrey Carter @ 2014-08-11  5:13 UTC (permalink / raw)


On 08/10/2014 09:51 PM, Laurent wrote:
>
> I was just hanging myself by thinking about a use of this pkg after the book.
> A thought about an program to manage my stuff at home (screws, paint, ...).
> So I don't know what info would put into the record.

The package is in the book to introduce you to certain concepts. I doubt if 
you'd ever actually use it; you'd be much more likely to use 
Ada.Containers.Doubly_Linked_Lists instead (ARM A.18.3). A review of 
Ada.Containers.Doubly_Linked_Lists, and its nested generic pkg Generic_Sorting, 
might expose you to another concept.

-- 
Jeff Carter
"Little blondes with long hair and short skirts and
boots and big chests and bright, witty, and perceptive."
Play It Again, Sam
128


^ permalink raw reply	[relevance 10%]

* Re: A question about syntax or semantics
  2014-05-18  2:47 10% ` Brad Moore
@ 2014-05-18 10:48  0%   ` Simon Wright
  0 siblings, 0 replies; 94+ results
From: Simon Wright @ 2014-05-18 10:48 UTC (permalink / raw)


Brad Moore <brad.moore@shaw.ca> writes:

> On 14-05-17 04:56 PM, Victor Porton wrote:
>>  From Ada2012 Reference Manual:
>>
>> arm2012.html/rm-4-1-3.html
>>
>> [[[
>> A selected_component that is not an expanded name shall resolve to denote
>> one of the following:
>>
>>      A view of a subprogram whose first formal parameter is of a tagged type
>> or is an access parameter whose designated type is tagged:
>> ]]]
>>
>> Why it is significant to have it only for the first formal parameter?
>>
>> Please explain with examples.
>>
>>
>
> This question is worded like an exam question, so rather than give the
> answer directly, I'll respond with another question that might shed
> some light on your question.
>
> with Ada.Containers.Doubly_Linked_Lists;
>
> procedure X is
>    package Integer_Lists is new
>        Ada.Containers.Doubly_Linked_Lists (Element_Type => Integer);
>     List1, List2 : Integer_Lists.List;
> begin
>    List1.Append(1);
>    List2.Append(2);
>
>    List1.Move(List2);
> end;
>
> If we didn't have the rule that you are asking about, what could we
> say about the Move call in the example above? Which list is the
> Source, and which list is the Target parameter? Is List1 getting moved
> into List2, or is it the other way around?

Well, considering the various assembler languages around, I'd still be
confused but for different reasons: given "mov r0,r1" does r1 receive
the value in r0 (which is what I'd expect, my first encounter with a
'normal' assembler having been MACRO-32) or does r0 receive the value in
r1?


^ permalink raw reply	[relevance 0%]

* Re: Termination of tasks waiting on a protected queue
  2014-05-18  7:32  4% Termination of tasks waiting on a protected queue Natasha Kerensikova
@ 2014-05-18  9:24  0% ` anon
  0 siblings, 0 replies; 94+ results
From: anon @ 2014-05-18  9:24 UTC (permalink / raw)


try using a Select / terminate statements

      task body Worker is
         Job : Job_Description;
      begin
         loop
           select
              Queue.Get_Next (Job);
              <actually to the job>
           or
              terminate ;
           end select ;
         end loop;
      end Worker;


In <slrnlngofv.i0l.lithiumcat@nat.rebma.instinctive.eu>, Natasha Kerensikova <lithiumcat@instinctive.eu> writes:
>Hello,
>
>I have been having a task termination issue, and I'm wondering whether I
>got my design wrong or whether I'm missing something, so I ask you to
>help me on that.
>
>The basic need is delegating potentially long jobs to a dedicated task
>(or pool of tasks) so that the program flow generating the jobs and
>continue quickly. I furthermore assume that the jobs are "fire and
>forget", that there is no need to report anything about completion (or
>lack of thereof) to the code that generated the jobs (or more
>realistically, that reporting is performed through channels outside of
>the scope of the problem).
>
>So I went with the basic design below:
>
>   package Example is
>      type Job_Description is private;
>
>      function Create_Job (...) return Job_Description;
>      procedure Enqueue_Job (Job : in Job_Description);
>
>   private
>
>      package Job_Lists is new Ada.Containers.Doubly_Linked_Lists
>        (Job_Description);
>
>      protected Queue is
>         procedure Append (Job : in Job_Description);
>         entry Get_Next (Job : out Job_Description);
>      private
>         List : Job_Lists.List;
>         Has_Job : Boolean := False;
>      end Queue;
>
>      task Worker is
>      end Worker;
>   end Example;
>
>   package body Example is
>      procedure Enqueue_Job (Job : in Job_Description) is
>      begin
>         Queue.Append (Job);
>      end Enqueue_Job;
>
>      protected body Queue is
>         procedure Append (Job : in Job_Description) is
>         begin
>            List.Append (Job);
>            Has_Job := True;
>         end Append;
>
>         entry Get_Next (Job : out Job_Description)
>            when Has_Job is
>         begin
>            Job := List.First_Element;
>            List.Delete_First;
>            Has_Job := not List.Is_Empty;
>         end Get_Next;
>      end Queue;
>
>      task body Worker is
>         Job : Job_Description;
>      begin
>         loop
>            Queue.Get_Next (Job);
>            <actually to the job>
>         end loop;
>      end Worker;
>   end Example;
>
>As you might have guessed, I have recently read a lot of material about
>Ravenscar profile, and as far as I can tell this example does match the
>profile, even though the original need happens in a much more relaxed
>environment.
>
>For example, without Ravenscar restrictions, the Worker task could
>easily be turned into a task type, and use an array of them to
>implement a pool of workers.
>
>The problem is, how to terminate cleanly the worker tasks in a
>non-Ravenscar environment when the main application is completed?
>
From my understanding of ARM 9.3, I need a terminate alternative in the
>worker tasks. But those can only exist in selective accepts, so I have
>to turn things around and make the task wait for one of its entries to
>be called, rather than wait for an external protected entry.
>
>But then, how can a worker task entry be used to solve my problem? A
>protected operation cannot call a task entry, because it's potentially
>blocking. The job generator cannot call the entry directly, because it
>would block when the task is not ready, so I still need a queue between
>the generator and the worker task.
>
>Alternatively, I could use a special value for Job_Description (or a new
>out parameter) to make the worker exit its infinite loop, and somehow
>make the protect Queue object aware that the master is completed, so
>that it can signal the worker task(s) to complete. But how can this be
>implemented? Since the tasks block the finalization of the master, I
>can't rely on a Finalize procedure to notify the protected object.
>
>
>Thanks in advance for your help,
>Natasha



^ permalink raw reply	[relevance 0%]

* Termination of tasks waiting on a protected queue
@ 2014-05-18  7:32  4% Natasha Kerensikova
  2014-05-18  9:24  0% ` anon
  0 siblings, 1 reply; 94+ results
From: Natasha Kerensikova @ 2014-05-18  7:32 UTC (permalink / raw)


Hello,

I have been having a task termination issue, and I'm wondering whether I
got my design wrong or whether I'm missing something, so I ask you to
help me on that.

The basic need is delegating potentially long jobs to a dedicated task
(or pool of tasks) so that the program flow generating the jobs and
continue quickly. I furthermore assume that the jobs are "fire and
forget", that there is no need to report anything about completion (or
lack of thereof) to the code that generated the jobs (or more
realistically, that reporting is performed through channels outside of
the scope of the problem).

So I went with the basic design below:

   package Example is
      type Job_Description is private;

      function Create_Job (...) return Job_Description;
      procedure Enqueue_Job (Job : in Job_Description);

   private

      package Job_Lists is new Ada.Containers.Doubly_Linked_Lists
        (Job_Description);

      protected Queue is
         procedure Append (Job : in Job_Description);
         entry Get_Next (Job : out Job_Description);
      private
         List : Job_Lists.List;
         Has_Job : Boolean := False;
      end Queue;

      task Worker is
      end Worker;
   end Example;

   package body Example is
      procedure Enqueue_Job (Job : in Job_Description) is
      begin
         Queue.Append (Job);
      end Enqueue_Job;

      protected body Queue is
         procedure Append (Job : in Job_Description) is
         begin
            List.Append (Job);
            Has_Job := True;
         end Append;

         entry Get_Next (Job : out Job_Description)
            when Has_Job is
         begin
            Job := List.First_Element;
            List.Delete_First;
            Has_Job := not List.Is_Empty;
         end Get_Next;
      end Queue;

      task body Worker is
         Job : Job_Description;
      begin
         loop
            Queue.Get_Next (Job);
            <actually to the job>
         end loop;
      end Worker;
   end Example;

As you might have guessed, I have recently read a lot of material about
Ravenscar profile, and as far as I can tell this example does match the
profile, even though the original need happens in a much more relaxed
environment.

For example, without Ravenscar restrictions, the Worker task could
easily be turned into a task type, and use an array of them to
implement a pool of workers.

The problem is, how to terminate cleanly the worker tasks in a
non-Ravenscar environment when the main application is completed?

From my understanding of ARM 9.3, I need a terminate alternative in the
worker tasks. But those can only exist in selective accepts, so I have
to turn things around and make the task wait for one of its entries to
be called, rather than wait for an external protected entry.

But then, how can a worker task entry be used to solve my problem? A
protected operation cannot call a task entry, because it's potentially
blocking. The job generator cannot call the entry directly, because it
would block when the task is not ready, so I still need a queue between
the generator and the worker task.

Alternatively, I could use a special value for Job_Description (or a new
out parameter) to make the worker exit its infinite loop, and somehow
make the protect Queue object aware that the master is completed, so
that it can signal the worker task(s) to complete. But how can this be
implemented? Since the tasks block the finalization of the master, I
can't rely on a Finalize procedure to notify the protected object.


Thanks in advance for your help,
Natasha

^ permalink raw reply	[relevance 4%]

* Re: A question about syntax or semantics
  @ 2014-05-18  2:47 10% ` Brad Moore
  2014-05-18 10:48  0%   ` Simon Wright
  0 siblings, 1 reply; 94+ results
From: Brad Moore @ 2014-05-18  2:47 UTC (permalink / raw)


On 14-05-17 04:56 PM, Victor Porton wrote:
>  From Ada2012 Reference Manual:
>
> arm2012.html/rm-4-1-3.html
>
> [[[
> A selected_component that is not an expanded name shall resolve to denote
> one of the following:
>
>      A view of a subprogram whose first formal parameter is of a tagged type
> or is an access parameter whose designated type is tagged:
> ]]]
>
> Why it is significant to have it only for the first formal parameter?
>
> Please explain with examples.
>
>

This question is worded like an exam question, so rather than give the 
answer directly, I'll respond with another question that might shed some 
light on your question.

with Ada.Containers.Doubly_Linked_Lists;

procedure X is
    package Integer_Lists is new
        Ada.Containers.Doubly_Linked_Lists (Element_Type => Integer);
     List1, List2 : Integer_Lists.List;
begin
    List1.Append(1);
    List2.Append(2);

    List1.Move(List2);
end;

If we didn't have the rule that you are asking about, what could we say 
about the Move call in the example above? Which list is the Source, and 
which list is the Target parameter? Is List1 getting moved into List2, 
or is it the other way around?

Brad

^ permalink raw reply	[relevance 10%]

* Re: Should Inline be private in the private part of a package spec?
  @ 2012-08-23 12:45  7%                                     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 94+ results
From: Dmitry A. Kazakov @ 2012-08-23 12:45 UTC (permalink / raw)


On Thu, 23 Aug 2012 13:33:57 +0200, Georg Bauhaus wrote:

> On 23.08.12 12:13, Dmitry A. Kazakov wrote:
>> Nobody needs either parsing or guessing in order to exchange structured
>> data.
> 
> Nobody needs either parsing or guessing in order to understand data
> of *known* structure. Which is the point.

Structured data cannot have unknown structure. Furthermore, you already
tried to praise XML for being able to define a structure. Now if the
structure is unknown, then the structure the XML description promotes maps
to what? It is even worse than to inadequately describe something existent.
What XML would do in this case would be outright lie.

But of course, you didn't meant that. You meant a tautology: a description
of an object describes the object (and its structure as well).

> When endpoints lack this
> knowledge and there exists no way of obtaining the knowledge from
> elsewhere, then hints in the data will help.

Nonsense. When an object is transmitted so goes its structure whatever it
be. As such it cannot be unknown to the peer which reconstructs the object
by deserializing it. If the structure were unknown but necessary, the
object could not be deserialized.

But we are running in circles. The capacities of XML for describing
structures of complex objects was already discussed. See
Ada.Containers.Doubly_Linked_Lists.

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



^ permalink raw reply	[relevance 7%]

* Re: GNAT GPL 2012 bug of iterator?
  2012-06-27  6:43 10% GNAT GPL 2012 bug of iterator? kylix
@ 2012-06-27  7:46  0% ` Martin
  0 siblings, 0 replies; 94+ results
From: Martin @ 2012-06-27  7:46 UTC (permalink / raw)


On Wednesday, June 27, 2012 7:43:19 AM UTC+1, kylix wrote:
> I try to compile the test code under GNAT GPL 2012, and it give a error message:
> gcc -c -O2 test.adb
> test.adb:42:13: invalid prefix in selected component "c"
> gnatmake: "test.adb" compilation error
> 
> It seems can't use list iterator in generic package.
> 
> Here are the test code:
> 
> pragma Ada_2012;
> with Ada.Text_IO;
> with Ada.Containers, Ada.Containers.Doubly_Linked_Lists;
> use Ada.Containers;
> procedure test is
> 
>    package Foo is
> 
>       type Rect_Type is tagged record
> 	 w, h, a : Integer := 0;
>       end record;
> 
>       procedure Calc (this : in out Rect_Type);
> 
>       type Rect_Ptr is access Rect_Type;
>    end Foo;
> 
>    package body Foo is
> 
>       procedure Calc (this : in out Rect_Type) is
>       begin
> 	 this.a := this.w * this.h;
>       end Calc;
> 
>    end Foo;
> 
> 
>    generic
>    package Generic_Pkg is
>       use Foo;
>       package Lists is new Doubly_Linked_Lists(Foo.Rect_Type);
> 
>       procedure Calc (list : in out Lists.List);
> 
>    end Generic_Pkg;
> 
>    package body Generic_Pkg is
> 
>       procedure Calc (list : in out Lists.List) is
>       begin
> 	 for c of list loop
> 	    c.Calc; -- if this code not in generic package, it works fine
> 	 end loop;
>       end;
>    end Generic_Pkg;
> 
>    package Rect is new Generic_Pkg;
> 
>    rs : Rect.Lists.List;
> 
> begin
>    for i in 1 .. 5 loop
>       rs.Append ((others => i));
>    end loop;
>    Rect.Calc(rs);
>    for c of rs loop
>       Ada.Text_IO.Put_Line (Integer'Image(c.a));
>    end loop;
> end test;

Same message in GNAT Pro 7.1.0 [actually GNAT Pro 7.1.0w (20120523-45)]

-- Martin



^ permalink raw reply	[relevance 0%]

* GNAT GPL 2012 bug of iterator?
@ 2012-06-27  6:43 10% kylix
  2012-06-27  7:46  0% ` Martin
  0 siblings, 1 reply; 94+ results
From: kylix @ 2012-06-27  6:43 UTC (permalink / raw)


I try to compile the test code under GNAT GPL 2012, and it give a error message:
gcc -c -O2 test.adb
test.adb:42:13: invalid prefix in selected component "c"
gnatmake: "test.adb" compilation error

It seems can't use list iterator in generic package.

Here are the test code:

pragma Ada_2012;
with Ada.Text_IO;
with Ada.Containers, Ada.Containers.Doubly_Linked_Lists;
use Ada.Containers;
procedure test is

   package Foo is

      type Rect_Type is tagged record
	 w, h, a : Integer := 0;
      end record;

      procedure Calc (this : in out Rect_Type);

      type Rect_Ptr is access Rect_Type;
   end Foo;

   package body Foo is

      procedure Calc (this : in out Rect_Type) is
      begin
	 this.a := this.w * this.h;
      end Calc;

   end Foo;


   generic
   package Generic_Pkg is
      use Foo;
      package Lists is new Doubly_Linked_Lists(Foo.Rect_Type);

      procedure Calc (list : in out Lists.List);

   end Generic_Pkg;

   package body Generic_Pkg is

      procedure Calc (list : in out Lists.List) is
      begin
	 for c of list loop
	    c.Calc; -- if this code not in generic package, it works fine
	 end loop;
      end;
   end Generic_Pkg;

   package Rect is new Generic_Pkg;

   rs : Rect.Lists.List;

begin
   for i in 1 .. 5 loop
      rs.Append ((others => i));
   end loop;
   Rect.Calc(rs);
   for c of rs loop
      Ada.Text_IO.Put_Line (Integer'Image(c.a));
   end loop;
end test;



^ permalink raw reply	[relevance 10%]

* Re: Pop function
  @ 2011-12-15 21:25  8%           ` Jeffrey Carter
  0 siblings, 0 replies; 94+ results
From: Jeffrey Carter @ 2011-12-15 21:25 UTC (permalink / raw)


On 12/15/2011 02:02 PM, Simon Wright wrote:
> "Dmitry A. Kazakov"<mailbox@dmitry-kazakov.de>  writes:
>
>> On Thu, 15 Dec 2011 12:57:47 -0700, Jeffrey Carter wrote:
>>
>>> No, a public interface should never use access types, ever. Hiding
>>> those is what abstraction is about. Any public interface that uses
>>> access types is poorly designed.
>>
>> In that case there should be no linked lists at all. A linked list is per
>> its definition a set of elements accessed using pointers.
>
> I don't think that using the word "linked" in the name is the same as
> "using access types in the abstraction"!
>
> I've seen linked lists that were implemented (under the hood) with
> indices into an array of items.

Precisely. That's a bounded list; see PragmARC.List_Bounded_Unprotected for an 
example.

And see Ada.Containers.Doubly_Linked_Lists for an example of an unbounded list 
abstraction with no visible access types.

-- 
Jeff Carter
"I would never want to belong to any club that
would have someone like me for a member."
Annie Hall
41

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---



^ permalink raw reply	[relevance 8%]

* Re: Booch Components question
  @ 2011-11-15 23:26  9%       ` Jeffrey Carter
  0 siblings, 0 replies; 94+ results
From: Jeffrey Carter @ 2011-11-15 23:26 UTC (permalink / raw)


On 11/15/2011 04:19 AM, Simon Wright wrote:
> Simon Wright<simon@pushface.org>  writes:
>
>> I think the only BC that I've used that doesn't have an equivalent in
>> the Standard is the Bag.
>
> Actually, Queues and Ordered (Priority) Queues too (before Ada2012).

FWIW, we had a problem with GNAT Pro's Ada.Containers.Doubly_Linked_Lists that 
went away when we replaced it with equivalent use of 
PragmARC.List_Unbounded_Unprotected. AdaCore was unable to find a problem with 
our use of the pkg nor with the pkg itself, so it remains a mystery. I was 
unable to see a problem in the pkg either. The list size was about 50,000 items. 
We haven't had a problem with the set or map containers.

-- 
Jeff Carter
"I feel as though somebody stepped on my tongue
with muddy feet."
Never Give a Sucker an Even Break
112



^ permalink raw reply	[relevance 9%]

* Re: discriminant questions
  @ 2011-09-21  7:48  8%                               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 94+ results
From: Dmitry A. Kazakov @ 2011-09-21  7:48 UTC (permalink / raw)


On Tue, 20 Sep 2011 13:19:32 -0700 (PDT), Maciej Sobczak wrote:

> On Sep 20, 6:48�pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
> 
>>>> Linked list is not a container,
>>
>>> We might be using different definitions, then.
>>
>> "an object used for or capable of holding, esp for transport or storage,
>> such as a carton, box, etc."
> 
> OK, so on the computer programming discussion group you are using a
> generic definition from The Free Dictionary, which contains the
> following disclaimer at the bottom of the page:

Yes, because we are not discussing something well defined.

>> Linked list is a data structure which may serve as an implementation of a
>> container.
> 
> That depends on your definition. According to mine (cited above)
> linked list is a container.

According to mine, it is only if implements the interface of a container
object, e.g. has list-wide operations applied to the container as a whole.
(E.g. Ada.Containers.Doubly_Linked_Lists is indeed a container)

In general case lists, trees, graphs are not containers, because the
interface is ineffective to implement. This also reflects the use cases of
lists and graphs which are not used as containers are.

The point is that it is the usage and interface which tell if the thing is
a container, not its internal structure, e.g. doubly-linked elements.

>>> We have to take into account the physicality of computations, unless
>>> some completely different model is invented (and delivered).
>>
>> Yes, that is why forcing referential semantics is bad.
> 
> Nobody is forcing referential semantics, although it might be the most
> natural and efficient solution for iterators.

Of course it does, because the iterator refers to the container and to an
element in that container. Which is evidently fragile as any reference when
the container and its element mutate. It is also bad for generic
programming, because the semantics of the side-effects depends on the
implementation, i.e. the internal structure of the container.

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



^ permalink raw reply	[relevance 8%]

* Re: S-expression I/O in Ada
  2010-08-25  1:56  5%         ` Jeffrey Carter
@ 2010-08-25 12:18  0%           ` Natasha Kerensikova
  0 siblings, 0 replies; 94+ results
From: Natasha Kerensikova @ 2010-08-25 12:18 UTC (permalink / raw)


On 2010-08-25, Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> wrote:
> On 08/24/2010 04:41 AM, Natasha Kerensikova wrote:
>> Does anybody have an idea about how to solve this issue?
>
> What issue? You haven't demonstrated that a deep copy is a problem anywhere 
> outside your mind. If you implement this and find that actual use exhausts 
> memory or takes longer than the user is willing to wait (~2 sec) then
> you have something to worry about.

Well, if it were about performances I would completely agree with you:
this is way too early in the development process to care about
performances or optimization.

However it is more about security. I guess it's a bad habit from C, but
I can't make a design or write some code without considering how it can
be abused. And I acknowledge the Ada compiler does a lot to free the
programmer from such considerations.

The deep copy won't be a problem for all the real-life cases I've ever
encountered so far, which is still quite a decent amount. However it
requires only one specially-crafted input from a single attacker to
bring the system on its knees (well, honestly I don't know how much an
Ada deep copy costs, but I do know how much a memcpy() costs and I'm
sure Ada deep copy is not cheaper).

> This is called "renaming as body": you implement the declaration with
> a renames 
>
> This requires that both subprograms have the same parameter and result
> type profile.

Thanks a lot for letting me know of the at possibility.

However I'm afraid the type profile is the issue here. Maybe I did it
wrong, but I didn't manage to get to compile any of my attempts at using
a package-provided type as the private implementation of a public type.

And if the public type doesn't match the package-provided type, none of
the package-provided subprograms can be used as publicly exposed
subprograms.

>> I still can't estimate how bad or inelegant
>> or ugly are explicit access. I guess even in Ada they have some niche
>> use, and avoiding expensive copy can be one them, right?
>
> They are needed to implement things like Ada.Containers.Doubly_Linked_Lists.

Yes, and I have the feeling the package I'm trying to write can thought
of as the same level as Ada standard containers: it's just a kind of
branching simply-linked list, with a predefined Element_Type instead of
a generic one.

That's why I came to think using accesses here might be legitimate, but
then again I still don't know how biased I am from my C pointer
juggling past. Hence my asking for external, hopefully less biased,
opinions.

>>     procedure String_To_Atom(S : in String; A : out Atom_Data);
>>     procedure Atom_To_String(A : in Atom_Data; S : out String);
>
> These are only partly specified. What happens if S'Length /= A'Length?

Maybe I should have kept them private.

If the source is shorter than the destination, the destination is
partially filled an everything continues; if the destination is shorter,
an exception is raised.

Should this kind of information be put as comments after the procedure
declaration?

> What happens if Element isn't an Atom?
>
> What happens when Element isn't a List?

Constraint_Error is raised, which felt like the right thing to do. At
first I used to explicitly check the node type, and explicitly raised the
exception, until I discovered that the compiler already does this when
casting the input Node'Class object into Atom or List.



Thanks a lot for your comments (even those I snipped here, have been
read and acknowledged),
Natasha



^ permalink raw reply	[relevance 0%]

* Re: S-expression I/O in Ada
  @ 2010-08-25  1:56  5%         ` Jeffrey Carter
  2010-08-25 12:18  0%           ` Natasha Kerensikova
  0 siblings, 1 reply; 94+ results
From: Jeffrey Carter @ 2010-08-25  1:56 UTC (permalink / raw)


On 08/24/2010 04:41 AM, Natasha Kerensikova wrote:
>
> Does anybody have an idea about how to solve this issue?

What issue? You haven't demonstrated that a deep copy is a problem anywhere 
outside your mind. If you implement this and find that actual use exhausts 
memory or takes longer than the user is willing to wait (~2 sec) then you have 
something to worry about.

> Another point I discovered while writing this implementation, is that I
> end up writing a lot of wrappers over the container's functions. Would
> it be possible to somehow define List and Cursors directly as instances
> of the container respective types, and to expose directly container's
> functions? All this while maintaining the type hiding, I don't want to
> expose the container, and just want to specify "I expose this and that
> functions" and tell in the body "oh by the way, this and that functions
> are just public names of this and that container functions". This way
> the code would be lighter but still as flexible (whenever I'm not
> satisfied with container functions, or whenever I want to change the
> container, I just have to (re)write the publicly exposed functions
> without changing the specification).

This is called "renaming as body": you implement the declaration with a renames 
of another subprogram:

function F (I : Integer) return Integer;

and later

package P is new Something (...);

function F renames P.F;

This requires that both subprograms have the same parameter and result type profile.

> I still can't estimate how bad or inelegant
> or ugly are explicit access. I guess even in Ada they have some niche
> use, and avoiding expensive copy can be one them, right?

They are needed to implement things like Ada.Containers.Doubly_Linked_Lists.

> Last point, I had trouble finding names. I read the Ada 95 Quality and
> Style Guide, and I find it difficult to follow. For example, I was
> tempted to call "Atom" the public array representation, the internal
> node type, and the function taking a Cursor and returning the public
> array representation. I was tempted to call "Node_Type" the public
> enumeration type, the function taking a Cursor and returning the type of
> the pointed node, and (not in this implementation but in some other
> attempts) the internal object discriminant name.

One thing about choosing names: the fewer names you have to choose, the less of 
an issue it is. If you use a Boolean for the discriminant, for example, then you 
don't need to choose names for the type of the discriminant or its values. 
Overloading can also help reduce the number of unique names. Your procedures 
String_To_Atom and Atom_To_String could be named To_Atom and To_String, same as 
your functions, just as you did later with procedures and functions named Next 
and Previous for Cursor.

A and S are terrible parameter names for these procedures. I would probably use 
Value and Image, respectively.

> package S_Expressions is
>
>     -----------
>     -- Types --
>     -----------

This is a worthless comment; we can tell that these are type declarations.

It's also not a good way to structure your code. Logically related things should 
be grouped together, not grouped by an incidental relationship such as "these 
are all types". You might want to group all declarations relating to Atoms, for 
example, then all relating to Lists, and so on.

>     type Node_Kind is (Node_Atom, Node_List);

These seem backward from an English usage point of view. Both are nodes, so the 
rest is a modifier that indicates the kind of node. In English, modifiers 
usually come before the thing they modify, so Atom_Node and List_Node would be 
more natural. It also puts the important difference between the 2 first, where 
it is immediately apparent.

>     procedure String_To_Atom(S : in String; A : out Atom_Data);
>     procedure Atom_To_String(A : in Atom_Data; S : out String);

These are only partly specified. What happens if S'Length /= A'Length?

>     procedure Counts(sexp : in List; Atom_Count, List_Count : out Count_Type);
>     function Atom_Count(sexp : in List) return Count_Type;
>     function List_Count(sexp : in List) return Count_Type;
>     function Node_Count(sexp : in List) return Count_Type;

These are problematical. I'd use Length rather than Node_Count, but I'm not sure 
what I'd name the others.

>
>     function Is_Atom(Element : in Cursor) return Boolean;
>     function Is_List(Element : in Cursor) return Boolean;
>     function Kind_Of(Element : in Cursor) return Node_Kind;

Is_* is good, but I'd just use Kind for the 3rd.

>     function Atom_Size(Element : in Cursor) return Natural;
>     function Atom_Contents(Element : in Cursor) return Atom_Data;
>     function Atom_To_String(Element : in Cursor) return String;

Again, Length, Contents, and To_String (or Image). What happens if Element isn't 
an Atom?

>     procedure Query_List(Element : in Cursor;
>                          Process : not null access procedure
>                                         (Sub_Sexp : in List));
>     function Sublist_First(Element : in Cursor) return Cursor;
>     function Sublist_Last(Element : in Cursor) return Cursor;

What happens when Element isn't a List?

-- 
Jeff Carter
"Help! Help! I'm being repressed!"
Monty Python & the Holy Grail
67

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---



^ permalink raw reply	[relevance 5%]

* Re: ANN: Ada 2005 Math Extensions, 20100810 release
  @ 2010-08-13 13:48  8%           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 94+ results
From: Dmitry A. Kazakov @ 2010-08-13 13:48 UTC (permalink / raw)


On Fri, 13 Aug 2010 15:31:30 +0200, Yannick Duch�ne (Hibou57) wrote:

> You mean the _G suffis became a somewhat de-facto standard ?

I meant the prefix Generic_. However the standard has no clear policy on
that:

Ada.Text_IO.Integer_IO
Ada.Containers.Doubly_Linked_Lists
Ada.Numerics.Generic_Complex_Arrays

>> Sometimes you need to "rename" formal types as well:
>>
>> generic
>>    type Foo is ...
>> package Generic_S is
>>    subtype Foo_Of is Foo; -- What a mess!
> 
> We already talked about these cases. Do you remember the thread's title ?  
> (I would like to get it back to read it again).

I think it popped up more than once.

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



^ permalink raw reply	[relevance 8%]

* Re: S-expression I/O in Ada
  @ 2010-08-13 10:30  9%     ` Georg Bauhaus
  0 siblings, 0 replies; 94+ results
From: Georg Bauhaus @ 2010-08-13 10:30 UTC (permalink / raw)


On 13.08.10 10:56, Natacha Kerensikova wrote:

> Ada arrays are statically sized,

Not quite, but I think you mean that once an array is allocated, you
can't add more components than are declared by the index constraint?
Example:

procedure Uses_Array (N : Positive; ...) is

   X : array (1 .. N) of Character;  -- now fixed to N compoments

begin...

But Ada's Container packages can provide for the desired flexibility.
There are containers of homogeneous components and containers of
heterogeneous components.  The latter have _Indefinite in their
package's names.  Example:

 package Vecs is new Ada.Containers.Indefinite_Vectors
     (Element_Type => Types.Heterogenous'Class,
      Index_Type => Positive,
      "=" => Types.Eq);

(Vecs.Vector objects will grow as needed.)

Another option is to instantiate a "definite" container generic with
a pointer type, which is definite.  Its access values will point
to any object in some hierarchy.  (This can mean pointers to
any objects that share the same interface (Ada 2005 keyword),
so types need not even be rooted at the same one parent type,
I think). For example

   package S_Lists is new Ada.Containers.Doubly_Linked_Lists
     (Element_Type => Some_Hier_Ptr,
      "=" => ...);


Georg



^ permalink raw reply	[relevance 9%]

* Re: S-expression I/O in Ada
  @ 2010-08-01 18:25  8% ` Jeffrey Carter
      2 siblings, 0 replies; 94+ results
From: Jeffrey Carter @ 2010-08-01 18:25 UTC (permalink / raw)


On 08/01/2010 05:17 AM, Natacha Kerensikova wrote:
>
> To describe briefly S-expressions, I consider them to be the simplest
> existing data organization beyond raw sequences of bits. They are
> basically lists of elements, each element being either a list or an
> atom, and atoms being raw sequences of bits.

You might very well be able to use something like:

package Byte_Lists is new Ada.Containers.Vectors (Index_Type => Positive, 
Element_Type => System.Storage_Elements.Storage_Element);

type Content_ID is (Atom, List);

type S_Expression;
type S_Expression_Ptr is access all S_Expression;

type S_Expression_Element (Content : Content_ID := Atom) is record
    case Content is
    when Atom =>
       Byte : Byte_Lists.Vector;
    when List =>
       Ptr : S_Expression_Ptr;
    end case;
end record;

package S_Expression_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Element_Type => S_Expression_Element);

type S_Expression is new S_Expression_Lists.List;

If you can use unbounded strings as Brenta suggested, instead of an unbounded 
array of bytes (Storage_Element), then this would be even simpler.

-- 
Jeff Carter
"People called Romanes, they go the house?"
Monty Python's Life of Brian
79

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---



^ permalink raw reply	[relevance 8%]

* Re: Types, packages & objects : the good old naming conventions question (without religious ware)
  @ 2009-10-31 11:58  7%       ` Stephen Leake
  0 siblings, 0 replies; 94+ results
From: Stephen Leake @ 2009-10-31 11:58 UTC (permalink / raw)


Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:

> Stephen Leake schrieb:
>> Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:
>> 
>>> Hibou57 (Yannick Duch�ne) schrieb:
>>>
>>>> There is on the other hand, this other convention, which came from
>>>> Pascal I suppose : the one which ends types name with the suffix _Type
>>> If you can't find a name for an object, ask more questions
>>> about it, its use, its relations, the programmer, its purpose,
>>> his purpose, etc:
>>> What is the role of the object?  Does the role lead to a name?
>> 
>> Why should I have to waste time on this?
>
> Because the time "wasted" on thinking about the roles (properties,
> relations, ...) of named entities in your programs, and
> then not being silent about your results, instead naming the
> entities suitably according to your results, and explicitly
> saying what you mean, is
>
> (a) spent anyway, though to different extents, on this very
>     issue

Yes, but that applies to both the object name and the type name;
making them _different_ requires _extra_ effort.

> P1 (in the kitchen): "P2? Mind giving me that?"
> P2 (in the living room): "What?"
> P1: "That thing over there."
> P2: "Where?"
> P1 (approaches):  "There." (P2 moves) "No, there."
> "No, not that, that!"

This is _not_ a good analogy; "that" is not a subprogram parameter in
the kitchen!

>>     procedure Sort (List : in out List; Order : in Order_Type);
>
> "List" is a darn bad abstraction name here!  

Nonsense; it is _precisely_ what I want; a list of abstract objects.

You can't avoid the naming problem by changing the context!

Here are the similar definitions from
Ada.Containers.Indefinite_Doubly_Linked_Lists. I hope you won't start
arguing that is a bad abstraction.

package Ada.Containers.Indefinite_Doubly_Linked_Lists is

   type List is tagged private;

   generic
      with function "<" (Left, Right : Element_Type) return Boolean is <>;
   package Generic_Sorting is

      function Is_Sorted (Container : List) return Boolean;
   end Generic_Sorting;
end Ada.Containers.Indefinite_Doubly_Linked_Lists;

Note that it uses _Type for Element!

How is that better than this:

package Ada.Containers.Indefinite_Doubly_Linked_Lists is

   type List_Type is tagged private;

   generic
      with function "<" (Left, Right : Element_Type) return Boolean is <>;
   package Generic_Sorting is

      function Is_Sorted (List : List_Type) return Boolean;
   end Generic_Sorting;

end Ada.Containers.Indefinite_Doubly_Linked_Lists;

> (For illustration we could similarly praise a ubuquituous type name
> such as "Bits" when what is meant is
> "Temperature_Sensor.Connector_Bits", say.)

But nothing specific is "meant" here; it is a generic, in the truest
English meaning of that word.

> (Rules here: Bits _of_ something, sensor _of_ something,
> these are examples following Tom Moran's comment, if I'm
> not mistaken. Names Sensor and Bits are really quite abstract.
> I would force them to be used for abstract types' names, at best.)

Yes, if you have a specific context and a specific meaning, then you
should use a specific name. The corollary is that if you have a
generic context, you should use a generic name.

> List in your original example without the Order parameter was
> almost certainly a Partial_Order even without an Order parameter
> in sight (since in the modified example you have given in this
> posting there is an Order parameter).  Next, the List is a partial
> order of element of some type.  Only in a reusable subprogram
> their type, if irrelevant, adds but noise (as per Bob Duff's rule).
> Since there is now an explicit Order parameter, I will assume
> that the List is really just a set of items without an order,
> and the name "List" only alludes to the mode of accessing
> the elements (sequentially, linked in some unknown way).

Ok.

> If I understand "Sort" meant as a generically useful procedure,
> then, as Dmitry has said, the first argument can be named "Container",
> since it contains the elements of the list (the type of Container).

Obviously; that's the approach Ada.Containers takes. It can also be
named "list", since that means exactly the same thing. Or the type can
be named "container", for the same reason.

There is the large risk that one person will decide on :

    procedure Sort (Container : in out List);

and another will choose:

    procedure Sort (List : in out Container);    

Now somebody has to decide, and one has to go back and make lots of
trivial (and therefore error-prone) edits.

I suppose one person could choose List_Type and the other
Container_Type, but at least that's a smaller fix to unify them.

> Without some hint to an order, a type name "List" says enough about
> the structure of the actual parameter (Container).
>
> "Order" is somewhat unspecific.  

Yes, deliberately.

> The "List" context helps when guessing that Order refers to a
> mathematical ordering relation. Its not a call to order, say, in a
> program controlling the president's electronic bell in some
> parliament.

Yes, obviously; this is a programming language context, not "the real
world".

> Inside the procedure, you might want to emphasize the links of
> the elements to be sorted.

Who said this was a linked list? Ada.Containers.Doubly_Linked_Lists
is, my original example doesn't care. I guess you could be refering to
abstract links.

See http://www.stephe-leake.org/ada/sal.html
sal-gen-alg-find_linear-sorted.ads for an abstract sort procedure. It
uses Container and Container_Type; "list" does have the connotation of
"linked list", "container" is slightly more abstract. But I often use
the name "list" for an implementation that happens to be an unbounded
array; "list" tends to imply some access order, meaning there is at
least First, Next, Is_Done. Containers don't have those functions.

> One way to achieve this is to rename the parameter "Container"
> to "Linked_Elements" (I'd think it is somewhat pompous, though.
> The implementer will know how to deal with the name Container.
> The reader of Sort's body will know what Container is, too.
> Because the type name, such as "Linked_List" gives the necessary
> information.)

That would be wrong; you are adding/imposing a structure that is not
necessarily there.

> generic
>     type Less_Equal is new Ordering with private;
> procedure Sort (Container : in out Linked_List);
>
> Is anything lost here?  

Yes! You have lost the fact that this is a generic procedure that
doesn't care about the internal structure of the list. You have also
lost the ability to specify the Order at run-time.

And "less_equal" implies a mathematical sort. All I really need for a
sort that produces a linear order is "goes_before". We tend to map all
things into numbers, so "less_equal" makes sense. But it's really
better to say "A goes before B", instead of "A is less than B".

"Ordering" could also imply a partial order, as for military rank; all
generals first, then all lieutenants, seargents, etc. Less_Equal can
mean that, but "Military_Rank" would be clearer.

>>> Naming conventions always make me think of features
>>> that a language does not offer.  I don't think this is
>>> the case with types and objects in Ada.
>> 
>> It _is_ the case for Ada! The feature "separate name spaces for types
>> and objects" is not offered by Ada. I'm not aware of a language that
>> does offer this feature, but it certainly is within the realm of
>> possibility.
>
> I think Dylan made an attempt, at least if one is satified with "car"
> being in a different namespace than "<car>".

Clearly it's a different name; it's a different lexeme. That's
the same as the _Type convention. 

> I'd still not pick essentially the same name for object Car
> and type Car though. Even if Ada had one namespace for types
> and one for other entities.  An object is never the same
> as a type, therefore it should be possible to distinguish
> the difference using words.

Yes! Car is distinguished from Car_Type, but List is not distinguished
from Container. Thank you for agreeing with me :).

Actually, I disagree with this statement; overloading types and
objects is fine, since the language does make the distinction clear
from context. In Dylan, I would use "car" and "<car>".

It sounds like you don't like overloading in the first place. How
about this: 

    adding integers is never the same as adding float; it should be
    possible to distinguish the difference using words

So you don't like "+" (Left, Right : in Integer) and "+" (Left, Right
: in Float)?

If you do like operator overloading, how is that different from
object/type overloading?

-- 
-- Stephe



^ permalink raw reply	[relevance 7%]

* Re: Question on initialization of packages
  @ 2008-06-17 16:39  5% ` Jeffrey R. Carter
  0 siblings, 0 replies; 94+ results
From: Jeffrey R. Carter @ 2008-06-17 16:39 UTC (permalink / raw)


Reinert Korsnes wrote:
> I try to use a stack in my Ada program.
> 
> Assume the package definition given below, 
> and the follow code in my program:
> 
>    type Message_t;
>    type Message_ta is access Message_t;

You probably don't need this access type. You generally don't need access types 
in Ada, except in the implementation of dynamic data structures.

>    package Message_Stack_p is new Stacks(Message_ta);
>    Send_Stack    : Message_Stack_p.Stack;
> 
> 
> Question: How can I be sure that "Send_Stack" is empty
> at the start of the program execution ?

By supplying an appropriate default initial value to objects of the type. In 
this case, the default initial value of type Stack is null, which you probably 
interpret as an empty stack.

> How can I make explicite that "Send_Stack" is empty in this case ?

Through comments in the specification of Stacks.

> generic
>   type Item is private;
> package Stacks is
>   type Stack is private;

Do you want Stack to have := and "="? Given that it's just an access value, it 
doesn't really make much sense for clients to assign or compare values. If you 
do want assignment, you either need to make it clear that Stack has reference 
assignment and comparison, rather than Ada's customary value assignment, or you 
need to make Stack's implementation controlled and override the Adjust and 
Finalize operations.

>   procedure Push(S: in out Stack; X:  in Item);
>   procedure  Pop(S: in out Stack; X: out Item);
>   function N_elements(S : Stack) return Integer;

A good rule for naming is to save the best name for parameters, and use a 
different name for the type. So I would use something like

type Element is private;
type Stack_Handle is private;

procedure Pop (Stack : in out Stack_Handle; Item : out Element);

so that procedure calls can look like

Pop (Stack => Operands, Item => Token);

> private
>   type Cell;
>   type Stack is access Cell;
>   type Cell is
>     record
>       Next : Stack;
>       N    : Integer;

What does it mean for N to be negative? If that's meaningless, use an 
appropriate subtype (such as Natural) to make that clear, and to let the 
run-time checks alert you if such a condition ever occurs.

>       Value: Item;
>     end record;
> end Stacks;

Probably you should keep N in the stack header:

type Cell_Ptr is access Cell;

type Stack is record
    Length : Natural  := 0;
    First  : Cell_Ptr := null;
end record;

rather than keeping copies in every item in the stack.

> package body Stacks is
> 
>   procedure Push(S: in out Stack; X: in Item) is
>   begin
>     if S /= null then
>        S := new Cell'(S,S.N+1,X);
>     else
>        S := new Cell'(S,1,X);
>     end if;
>   end;
> 
>   procedure Pop(S: in out Stack; X: out Item) is
>   begin
>     X := S.Value;
>     S := S.Next;
>   end;

Here you have a memory leak. Even if you fix that, if you store uncontrolled 
access values in the stack (as you're doing with your type Message_Ta), you may 
still have a memory leak.

>   function N_elements(S: Stack) return Integer is
>   begin
>     if S /= null then
>        return S.N;
>     else
>        return 0;
>     end if;
>   end;
> 
> end Stacks;

But really you shouldn't be implementing your stack ADT directly, and trying to 
do your memory management yourself. Instead implement it in terms of an existing 
sequence data structure, such as Ada.Containers.Doubly_Linked_Lists, and let 
that data structure do the work for you. Such an approach is more likely to be 
correct than doing it yourself. The only reason you would implement your stack 
directly is if this is a learning exercise to learn about the use of access 
types. In that case you will throw it away when you're done, and use a stack 
package built on top of an existing data structure for "real" code.

You can probably find a stack package in one of the many Ada libraries that are 
available. Check adapower.com and adaworld.com. If you don't mind using Ada 95 
(everything you've written is valid Ada 95), there are sequential and protected 
stack packages available as part of the PragmAda Reusable Components:

http://pragmada.home.mchsi.com/

-- 
Jeff Carter
"I'm a kike, a yid, a heebie, a hook nose! I'm Kosher,
Mum! I'm a Red Sea pedestrian, and proud of it!"
Monty Python's Life of Brian
77



^ permalink raw reply	[relevance 5%]

* Re: Learning tagged types
  2008-02-22 23:23  9% Learning tagged types mhamel_98
@ 2008-02-23  0:04  0% ` Adam Beneschan
  0 siblings, 0 replies; 94+ results
From: Adam Beneschan @ 2008-02-23  0:04 UTC (permalink / raw)


On Feb 22, 3:23 pm, mhamel...@yahoo.com wrote:
> Hello, this is a representative bit of code I use and, experimenting
> with tagged types, want to know if/how this can be cleanly moved to a
> more object oriented format.  I think I want proc and def to be
> abstract procedures, that requires the "object" Proc_Def itself to be
> abstract, that means declaring new packages everytime I have a new
> Proc_Def?  Thanks for any pointers (no pun intended),
>
> with Text_Io;
> with Ada.Containers.Doubly_Linked_Lists;
>
> procedure Tag_Test2 is
>
>   type Proc_Def;
>
>   type Proc_Ptr is access procedure (Def : Proc_Def;
>                                      Val : Float);
>   type Term_Ptr is access procedure (Def : Proc_Def);
>
>   type Proc_Def is
>     record
>       Name : String (1 .. 4);
>       Proc : Proc_Ptr;
>       Term : Term_Ptr;
>     end record;

I think what you want is to declare a root type instead of Proc_Def.
I don't know what you really want to call it, but you probably want to
make it an abstract type; then, instead of Proc_Ptr and Term_Ptr,
you'd declare "Proc" and "Term" or something like that to be primitive
operations of the root type.  E.g.

   type Root is abstract tagged
     record
       Name : String (1 .. 4);
     end record;

   procedure Proc (Def : Root;  Val : Float) is abstract;
   procedure Term (Def : Root) is abstract;

You do need to declare Root in a package specification, and Proc and
Term in the same specification.  (But the package could be nested
inside a procedure, if you really want it to.)

Then whenever you want to declare a particular version of this with
its own versions of Proc and Term (such as your Proc1 and Term1
below), you'd declare a type extension:

   type Some_Type is new Root with null record;

   overriding procedure Proc (Def : Some_Type;  Val : Float);
   overriding procedure Term (Def : Some_Type);

("overriding" is an Ada 2005 extension; it's not required, but is
there to help protect against accidents.  In Ada 95, just leave that
word off.)

A caveat: In Ada 95, Some_Type can't be declared inside a procedure
unless Root was declared earlier inside that same procedure.  In Ada
2005, this restriction is relaxed, but I still think you'll have to
follow it if you use it with Doubly_Linked_Lists---otherwise you could
create a list that points to a Some_Type object after Some_Type is no
longer visible.

Of course, Some_Type doesn't have to say "with null record".  If you
like, you can add additional fields---in fact, one of the purposes of
a more object-oriented style would be so that you can have additional
data for Some_Type that is just for that type and not for every type
in the class.

Now, instead of Proc_Def in the following declarations, you'd use
Root'Class since the type could be any type in the class:

>   package DLL is new Ada.Containers.Doubly_Linked_Lists (Proc_Def);
>   Proc_List : DLL.List;
>
>   procedure Insert_Proc (Def : Proc_Def) is
>   begin
>     Proc_List.Append (Def);
>   end Insert_Proc;
>
>   function Retrieve_Proc return Proc_Def is
>   begin
>     return Proc_List.First_Element;
>   end Retrieve_Proc;

The following would be the overriding bodies of Proc and Term for your
Some_Type type:

>   procedure Proc1 (Def : Proc_Def;  -- change this to Some_Type
>                    Val : Float) is
>   begin
>     Text_Io.Put_Line (Def.Name & ": processing - " & Val'Img);
>   end Proc1;
>
>   procedure Term1 (Def : Proc_Def) is  -- change this to Some_Type
>   begin
>       Text_Io.Put_Line (Def.Name & ": shutting down");
>   end Term1;
>
>   Test_Proc : Proc_Def;
>
> begin
>   Insert_Proc (("test", Proc1'access, Term1'access));

The above would become Insert_Proc (Some_Type' (Name => "test")).

>   Test_Proc := Retrieve_Proc;
>   Test_Proc.Proc (Test_Proc, 5.0);
>   Test_Proc.Term (Test_Proc);
> end Tag_Test2;

To answer your other question: no, you don't have to declare a new
package for every new type in the class.  Some programmers like doing
that, but that's a matter of style.

I haven't actually tried this.  You may have to fill in some of the
details, and I could have gotten one or two things wrong.  But
hopefully this will at least get you started.

                               -- Adam





^ permalink raw reply	[relevance 0%]

* Learning tagged types
@ 2008-02-22 23:23  9% mhamel_98
  2008-02-23  0:04  0% ` Adam Beneschan
  0 siblings, 1 reply; 94+ results
From: mhamel_98 @ 2008-02-22 23:23 UTC (permalink / raw)


Hello, this is a representative bit of code I use and, experimenting
with tagged types, want to know if/how this can be cleanly moved to a
more object oriented format.  I think I want proc and def to be
abstract procedures, that requires the "object" Proc_Def itself to be
abstract, that means declaring new packages everytime I have a new
Proc_Def?  Thanks for any pointers (no pun intended),

with Text_Io;
with Ada.Containers.Doubly_Linked_Lists;

procedure Tag_Test2 is

  type Proc_Def;

  type Proc_Ptr is access procedure (Def : Proc_Def;
                                     Val : Float);
  type Term_Ptr is access procedure (Def : Proc_Def);

  type Proc_Def is
    record
      Name : String (1 .. 4);
      Proc : Proc_Ptr;
      Term : Term_Ptr;
    end record;

  package DLL is new Ada.Containers.Doubly_Linked_Lists (Proc_Def);
  Proc_List : DLL.List;

  procedure Insert_Proc (Def : Proc_Def) is
  begin
    Proc_List.Append (Def);
  end Insert_Proc;

  function Retrieve_Proc return Proc_Def is
  begin
    return Proc_List.First_Element;
  end Retrieve_Proc;

  procedure Proc1 (Def : Proc_Def;
                   Val : Float) is
  begin
    Text_Io.Put_Line (Def.Name & ": processing - " & Val'Img);
  end Proc1;

  procedure Term1 (Def : Proc_Def) is
  begin
      Text_Io.Put_Line (Def.Name & ": shutting down");
  end Term1;

  Test_Proc : Proc_Def;

begin
  Insert_Proc (("test", Proc1'access, Term1'access));
  Test_Proc := Retrieve_Proc;
  Test_Proc.Proc (Test_Proc, 5.0);
  Test_Proc.Term (Test_Proc);
end Tag_Test2;



^ permalink raw reply	[relevance 9%]

* Re: Newbie's question [SOLVED]
  2008-02-11 14:31  9% Newbie's question Christos Chryssochoidis
@ 2008-02-11 16:28  0% ` Christos Chryssochoidis
  0 siblings, 0 replies; 94+ results
From: Christos Chryssochoidis @ 2008-02-11 16:28 UTC (permalink / raw)



I changed version of GNAT and now the code runs ok.



Christos Chryssochoidis wrote:
> 
> Hello,
> 
> I 'm experimenting with Ada, and I'm having trouble getting some toy 
> code running. The code is the following: (hope it isn't too complicated)
> 
> 
> -- This is a program to test passing subprograms as arguments to other 
> subprograms.
> -- It consists of a main program, "Test_Filter", and two nested 
> subprograms: "Filter" and "Greater_Equal_3". The "Filter" subprogram 
> takes as arguments an array of Integers and a function (predicate), and 
> returns an array of the same type, having only those elements of the 
> input array that satisfy the given predicate. For some reason that I 
> can't figure out, I'm getting a "segmentation fault" when I run the 
> executable. (It compiles fine.)
> 
> 
> with Ada.Containers.Doubly_Linked_Lists;
> with Ada.Text_IO;
> 
> procedure Test_Filter is
> 
>    subtype Index is Natural;
>    type Int_Array is array(Index range<>) of Integer;
> 
> 
>    function Filter(Elements : Int_Array; Predicate : not null 
> access                     function(Element : Integer) return 
> Boolean)                                 return Int_Array  is
>       package Int_Lists is new                                      
> Ada.Containers.Doubly_Linked_Lists(Element_Type => Integer);
>       Tmp_List : Int_Lists.List;
>       Result : access Int_Array;
>    begin
>       for I in Elements'Range loop
>          if Predicate(Elements(I)) then
>             Tmp_List.Append(Elements(I));
>          end if;
>       end loop;
> 
>       Result := new Int_Array(1..Index(Tmp_List.Length));
>   Copy_List:
>       declare
>          Tmp_List_Cursor : Int_Lists.Cursor := Tmp_List.First;
>          I : Integer := 1;
>       begin
>          while Int_Lists.Has_Element(Tmp_List_Cursor) loop
>             Result(I) := Int_Lists.Element(Tmp_List_Cursor);
>             Tmp_List_Cursor := Int_Lists.Next(Tmp_List_Cursor);
>             I := I + 1;
>          end loop;
>       end Copy_List;
> 
>       return Result.all;
> 
>    end Filter;
> 
>    function Greater_Equal_3(Element :Integer) return Boolean is
>    begin
>       if Element >= 3 then
>          return True;
>       else
>          return False;
>       end if;
>    end Greater_Equal_3;
> 
> 
>    Int_Array1 : Int_Array := Int_Array'(1,2,3,4,5);
>    Int_Array2 : Int_Array(1..3);
> 
> begin
>    Int_Array2 := Filter(Int_Array1, Greater_Equal_3'Access);
>    for I in Int_Array1'Range loop
>       Ada.Text_IO.Put_Line(Int_Array1(I)'Img);
>    end loop;
> 
>    Ada.Text_IO.Put_Line("");
> 
>    for I in Int_Array2'Range loop
>       Ada.Text_IO.Put_Line(Int_Array2(I)'Img);
>    end loop;
> 
> end Test_Filter;
> 
> 
> Thanks very much for any help.



^ permalink raw reply	[relevance 0%]

* Newbie's question
@ 2008-02-11 14:31  9% Christos Chryssochoidis
  2008-02-11 16:28  0% ` Newbie's question [SOLVED] Christos Chryssochoidis
  0 siblings, 1 reply; 94+ results
From: Christos Chryssochoidis @ 2008-02-11 14:31 UTC (permalink / raw)


Hello,

I 'm experimenting with Ada, and I'm having trouble getting some toy 
code running. The code is the following: (hope it isn't too complicated)


-- This is a program to test passing subprograms as arguments to other 
subprograms.
-- It consists of a main program, "Test_Filter", and two nested 
subprograms: "Filter" and "Greater_Equal_3". The "Filter" subprogram 
takes as arguments an array of Integers and a function (predicate), and 
returns an array of the same type, having only those elements of the 
input array that satisfy the given predicate. For some reason that I 
can't figure out, I'm getting a "segmentation fault" when I run the 
executable. (It compiles fine.)


with Ada.Containers.Doubly_Linked_Lists;
with Ada.Text_IO;

procedure Test_Filter is

    subtype Index is Natural;
    type Int_Array is array(Index range<>) of Integer;


    function Filter(Elements : Int_Array; Predicate : not null 
access 					function(Element : Integer) return Boolean) 								return 
Int_Array  is
       package Int_Lists is new 									 
Ada.Containers.Doubly_Linked_Lists(Element_Type => Integer);
       Tmp_List : Int_Lists.List;
       Result : access Int_Array;
    begin
       for I in Elements'Range loop
          if Predicate(Elements(I)) then
             Tmp_List.Append(Elements(I));
          end if;
       end loop;

       Result := new Int_Array(1..Index(Tmp_List.Length));
   Copy_List:
       declare
          Tmp_List_Cursor : Int_Lists.Cursor := Tmp_List.First;
          I : Integer := 1;
       begin
          while Int_Lists.Has_Element(Tmp_List_Cursor) loop
             Result(I) := Int_Lists.Element(Tmp_List_Cursor);
             Tmp_List_Cursor := Int_Lists.Next(Tmp_List_Cursor);
             I := I + 1;
          end loop;
       end Copy_List;

       return Result.all;

    end Filter;

    function Greater_Equal_3(Element :Integer) return Boolean is
    begin
       if Element >= 3 then
          return True;
       else
          return False;
       end if;
    end Greater_Equal_3;


    Int_Array1 : Int_Array := Int_Array'(1,2,3,4,5);
    Int_Array2 : Int_Array(1..3);

begin
    Int_Array2 := Filter(Int_Array1, Greater_Equal_3'Access);
    for I in Int_Array1'Range loop
       Ada.Text_IO.Put_Line(Int_Array1(I)'Img);
    end loop;

    Ada.Text_IO.Put_Line("");

    for I in Int_Array2'Range loop
       Ada.Text_IO.Put_Line(Int_Array2(I)'Img);
    end loop;

end Test_Filter;


Thanks very much for any help.



^ permalink raw reply	[relevance 9%]

* Re: Workqueues in Ada
  2007-07-30  6:47  8%             ` Niklas Holsti
@ 2007-07-30 15:56  0%               ` Matthew Heaney
  0 siblings, 0 replies; 94+ results
From: Matthew Heaney @ 2007-07-30 15:56 UTC (permalink / raw)


On Jul 30, 2:47 am, Niklas Holsti <niklas.hol...@nospam.please> wrote:


> Ada.Containers.Doubly_Linked_Lists has this operation:

[Description of Splice snipped]

> This seems to do what Dmitry suggested.

Yes, that's the exact intent.  You can implement a queue or ring or
whatever using the standard list container.




^ permalink raw reply	[relevance 0%]

* Re: Workqueues in Ada
  2007-07-28 17:00  6% Workqueues in Ada Wiktor Moskwa
                   ` (2 preceding siblings ...)
  2007-07-28 21:54  0% ` Robert A Duff
@ 2007-07-30 15:48  0% ` Matthew Heaney
  3 siblings, 0 replies; 94+ results
From: Matthew Heaney @ 2007-07-30 15:48 UTC (permalink / raw)


On Jul 28, 1:00 pm, Wiktor Moskwa <wiktorDOTmos...@gmail.com> wrote:
>
> The problem is that my poor implementation of workqueue is a
> bottleneck. A task takes a unit of work from a queue, processes it
> and puts it back at the and of the queue. Because the queue is
> Ada.Containers.Doubly_Linked_Lists there are lots of memory
> allocations and deallocations - that's a performance problem.

You can work around that using the Splice operations, which move nodes
from one list container to another.  You could use one list as a kind
of free-store, from where you get new nodes.  Instead of Deleting a
node from a list, splice it onto the free-store list; this eliminates
deallocation.






^ permalink raw reply	[relevance 0%]

* Re: Workqueues in Ada
  @ 2007-07-30  6:47  8%             ` Niklas Holsti
  2007-07-30 15:56  0%               ` Matthew Heaney
  0 siblings, 1 reply; 94+ results
From: Niklas Holsti @ 2007-07-30  6:47 UTC (permalink / raw)


Wiktor Moskwa wrote:
> On 29.07.2007, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> 
>>Doesn't it have "move X from the list A to the list B?" That should not
>>have any node allocation / deallocation overhead. In "simple components"
>>Append, Insert, Prepend have a version which takes the item from another or
>>same list and places it where required.
> 
> 
> Unfortunately it doesn't have such operation.

Ada.Containers.Doubly_Linked_Lists has this operation:

    procedure Splice (Target   : in out List;
                      Before   : in     Cursor;
                      Source   : in out List;
                      Position : in out Cursor);

The description (in RM A.18.3(114/2)) says: "... the element designated 
by Position is removed from Source and moved to Target, immediately 
prior to Before, ...".

This seems to do what Dmitry suggested.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 8%]

* Re: Workqueues in Ada
  2007-07-28 17:00  6% Workqueues in Ada Wiktor Moskwa
  2007-07-28 17:28  8% ` Dmitry A. Kazakov
  2007-07-28 17:31  0% ` Jeffrey R. Carter
@ 2007-07-28 21:54  0% ` Robert A Duff
  2007-07-30 15:48  0% ` Matthew Heaney
  3 siblings, 0 replies; 94+ results
From: Robert A Duff @ 2007-07-28 21:54 UTC (permalink / raw)


Wiktor Moskwa <wiktorDOTmoskwa@gmail.com> writes:

> The problem is that my poor implementation of workqueue is a 
> bottleneck. A task takes a unit of work from a queue, processes it 
> and puts it back at the and of the queue. Because the queue is 
> Ada.Containers.Doubly_Linked_Lists there are lots of memory
> allocations and deallocations - that's a performance problem.

I'm not clear on exactly what you're trying to do, but it sounds like
"units of work" get created and destroyed a lot less often than they get
added to and removed from the queue.  Consider using a doubly-linked
list with the links threaded through the units of work, so
adding/removing doesn't need to allocate/free anything -- just stir a
few pointers around.

> I consider making a circular list of nodes with "Next_To_Service"
> pointer going around as nodes are processed. I'll have to make
> sure that one node can be served by only one task at the time
> (probably by marking nodes as being served at the moment).
> New nodes joining and old leaving the system will be more
> difficult to implement correctly, I suppose.

I think the "marking nodes" thing is probably not a good idea.
It's complicated, and it doesn't scale well.

But if you have a max number of items in the queue at any time,
a circular buffer of pointers to units-of-work would do just fine.
The max number could be calculated at run time, and you could
even make it growable, if you wanted to (in which case "max" is a
misnomer.  ;-))

- Bob



^ permalink raw reply	[relevance 0%]

* Re: Workqueues in Ada
  2007-07-28 17:28  8% ` Dmitry A. Kazakov
@ 2007-07-28 17:52  0%   ` Wiktor Moskwa
    0 siblings, 1 reply; 94+ results
From: Wiktor Moskwa @ 2007-07-28 17:52 UTC (permalink / raw)


On 28.07.2007, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> I thought Ada.Containers.Doubly_Linked_Lists can move elements between
> lists without copying. Have you checked that?

I think the problem is that each time a task takes a unit from the queue
Delete is called and just after it Append - without a custom storage
pool malloc and free are called very often.

> You could also try an alternative implementation of doubly-linked lists and
> webs:
>
> http://www.dmitry-kazakov.de/ada/components.htm#Generic_Doubly_Linked_Web

It looks promising, especially with an ability to pass a storage pool
as a generic parameter. I'll check it out.

> Make it a protected object. A worker task calls to an entry of, requesting
> an item of work. The entry removes the first item from the list and returns
> it to the task via pointer. When the worker task finishes dealing with the
> item it calls to a protected object's procedure to queue the item back.

That's how it works now - I forgot to mention that my list is wrapped in 
a protected object, otherwise it wouldn't work :)
My idea of using a circular list is to call Delete and Append only when
new node joins the system or an old one leaves. During normal operations
a task will request new unit of work without deleting it from the queue.
It will be only marked as "currently in use". Other tasks will skip
this node - Next_To_Service pointer will move clockwise skipping nodes
that are serviced at the moment.

Thanks for your reply Dmitry.

-- 
Wiktor Moskwa



^ permalink raw reply	[relevance 0%]

* Re: Workqueues in Ada
  2007-07-28 17:00  6% Workqueues in Ada Wiktor Moskwa
  2007-07-28 17:28  8% ` Dmitry A. Kazakov
@ 2007-07-28 17:31  0% ` Jeffrey R. Carter
  2007-07-28 21:54  0% ` Robert A Duff
  2007-07-30 15:48  0% ` Matthew Heaney
  3 siblings, 0 replies; 94+ results
From: Jeffrey R. Carter @ 2007-07-28 17:31 UTC (permalink / raw)


Wiktor Moskwa wrote:
> The problem is that my poor implementation of workqueue is a 
> bottleneck. A task takes a unit of work from a queue, processes it 
> and puts it back at the and of the queue. Because the queue is 
> Ada.Containers.Doubly_Linked_Lists there are lots of memory
> allocations and deallocations - that's a performance problem.

A simple thing to do would be to replace Doubly_Linked_Lists with a 
protected, bounded queue, such as PragmARC.Queue_Bounded[_Blocking]. 
This will also serve to validate that it's the dynamic nature of 
Doubly_Linked_Lists that is causing the problem.

The PragmAda Reusable Components are available at

http://pragmada.home.mchsi.com/

-- 
Jeff Carter
"C's solution to this [variable-sized array parameters] has real
problems, and people who are complaining about safety definitely
have a point."
Dennis Ritchie
25



^ permalink raw reply	[relevance 0%]

* Re: Workqueues in Ada
  2007-07-28 17:00  6% Workqueues in Ada Wiktor Moskwa
@ 2007-07-28 17:28  8% ` Dmitry A. Kazakov
  2007-07-28 17:52  0%   ` Wiktor Moskwa
  2007-07-28 17:31  0% ` Jeffrey R. Carter
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 94+ results
From: Dmitry A. Kazakov @ 2007-07-28 17:28 UTC (permalink / raw)


On Sat, 28 Jul 2007 17:00:57 +0000 (UTC), Wiktor Moskwa wrote:

> The problem is that my poor implementation of workqueue is a 
> bottleneck. A task takes a unit of work from a queue, processes it 
> and puts it back at the and of the queue. Because the queue is 
> Ada.Containers.Doubly_Linked_Lists there are lots of memory
> allocations and deallocations - that's a performance problem.

I thought Ada.Containers.Doubly_Linked_Lists can move elements between
lists without copying. Have you checked that?

You could also try an alternative implementation of doubly-linked lists and
webs:

http://www.dmitry-kazakov.de/ada/components.htm#Generic_Doubly_Linked_Web

> I consider making a circular list of nodes with "Next_To_Service"
> pointer going around as nodes are processed. I'll have to make
> sure that one node can be served by only one task at the time
> (probably by marking nodes as being served at the moment).
> New nodes joining and old leaving the system will be more
> difficult to implement correctly, I suppose.

Make it a protected object. A worker task calls to an entry of, requesting
an item of work. The entry removes the first item from the list and returns
it to the task via pointer. When the worker task finishes dealing with the
item it calls to a protected object's procedure to queue the item back.

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



^ permalink raw reply	[relevance 8%]

* Workqueues in Ada
@ 2007-07-28 17:00  6% Wiktor Moskwa
  2007-07-28 17:28  8% ` Dmitry A. Kazakov
                   ` (3 more replies)
  0 siblings, 4 replies; 94+ results
From: Wiktor Moskwa @ 2007-07-28 17:00 UTC (permalink / raw)


Hello,

Few months ago I wrote about a distributed protocol simulator that
I was writing in Ada. I followed an advice to stop using a thread per
node and to implement a worker thread pool.
With the new architecture things improved a lot, all the overhead
of context switching has gone.

I defined a unit of work as one iteration of one node (checking if
new messages have come, processing messages, sending responses,
checking if it's time to run a periodic job, updating statistic).
I have a workqueue of above units and a pool of tasks that service
nodes.

The problem is that my poor implementation of workqueue is a 
bottleneck. A task takes a unit of work from a queue, processes it 
and puts it back at the and of the queue. Because the queue is 
Ada.Containers.Doubly_Linked_Lists there are lots of memory
allocations and deallocations - that's a performance problem.

I consider making a circular list of nodes with "Next_To_Service"
pointer going around as nodes are processed. I'll have to make
sure that one node can be served by only one task at the time
(probably by marking nodes as being served at the moment).
New nodes joining and old leaving the system will be more
difficult to implement correctly, I suppose.

What can you suggest?
I'm probably missing something obvious. 
Thanks in advance!

-- 
Wiktor Moskwa



^ permalink raw reply	[relevance 6%]

* Re: Impossible problem? A protected buffer to queue objects of a class-wide type
  @ 2007-04-13 17:02  8% ` Matthew Heaney
  0 siblings, 0 replies; 94+ results
From: Matthew Heaney @ 2007-04-13 17:02 UTC (permalink / raw)


On Apr 11, 6:34 am, "Phil Slater" <phil.sla...@baesystems.com> wrote:
> I've hit a brick wall. Every strategy I try doesn't work.

Won't the code below work?


> I need to write a generic package that exports a protected queue type that
> will act as a buffer for objects of a class-wide type.

That's fine.  You can declare the generic formal type as indefinite,
to make the package more general.

Note that I have used an Ada05 feature, extended return statement, to
return the class-wide object as the result of a function.  Is Ada05 is
not an option for you let me know and we'll figure something else out.


> My strategy is that
> when objects join the queue they are copied onto the heap,

Yes, that's what the solution below does.


> and an
> access-to-class-wide value is put onto the queue (could be array-based or
> linked-list-based - I don't mind).

I have created an internal buffer, implemented using the doubly-linked
list standard container, instantiated with an access type as the
generic actual.


> To retrieve an item from the queue, an
> access-to-class-wide value is removed from the queue, the heap object it
> designates is copied onto the stack, the heap object is deallocated, then
> the copy is returned.

Yes, the example below does that.


> The crux of the problem goes like this:
>
> (a) for the client code to retrieve an item, it needs to call a function; it
> can't be done through a procedure or entry "out" parameter since I can't
> declare an uninitialised variable of the class-wide type to pass as an
> actual parameter. So the client code needs to do something like this:
>     declare
>         Next_In_Line : Item'class := My_Buffer.Dequeue;  -- My_Buffer is the
> protected queue

The problem you're having is mixing layers of abstraction.  The queue
type below does indeed have a Deque function, and there is a
proctected object, but the protected object itself is an
implementation detail of the queue abstract data type.



> (b) To support this call, Dequeue must be written as a function. As such, it
> cannot change the protected queue. What I need is the "entry" functionality,
> since I want the Dequeue to wait if the queue is empty, and I want the item
> to be removed from the queue as well as retrieved.

Yes, you can do that, but you need two separate steps: the first step
is to use an entry (with a barrier) to remove the front item from the
queue's internal buffer (that's the protected object part), and then
return the value you removed from the internal buffer to the caller,
via a function (that's the abstract data type part).

In the example below I have used an extended return, since the return
type is indefinite.


> I cannot see a way through this problem, and am astounded that a language of
> this calibre seems to have rules that conspire together to make it appear
> impossible. What have I missed?

Use the Source, Luke!

--STX
private with Ada.Containers.Doubly_Linked_Lists;

generic
   type ET (<>) is private;

package Queues is

   type QT is limited private;

   function Deque (Q : not null access QT) return ET;

   procedure Enque (Q : in out QT; E : ET);

private

   type ET_Access is access ET;

   use Ada.Containers;
   package ET_Lists is new Doubly_Linked_Lists (ET_Access);

   protected type BT is
      entry Get (Obj : out ET_Access);
      procedure Put (Obj : ET_Access);
   private
      L : ET_Lists.List;
   end BT;

   type QT is limited record
     B : BT;
   end record;

end Queues;


with Ada.Unchecked_Deallocation;

package body Queues is

   procedure Free is new Ada.Unchecked_Deallocation (ET, ET_Access);

   protected body BT is

      entry Get (Obj : out ET_Access) when not L.Is_Empty is
      begin
         Obj := L.First_Element;
         L.Delete_First;
      end;

      procedure Put (Obj : ET_Access) is
      begin
         L.Append (Obj);
      end;

   end BT;

   function Deque (Q : not null access QT) return ET is
      Obj : ET_Access;

   begin
      Q.B.Get (Obj);

      return E : ET := Obj.all do
        Free (Obj);
      end return;
   end Deque;


   procedure Enque (Q : in out QT; E : ET) is
   begin
      Q.B.Put (ET_Access'(new ET'(E)));
   end;


end Queues;


Regards,
Matt




^ permalink raw reply	[relevance 8%]

* Re: Ada.Containers.Doubly_Linked_Lists
  2007-02-07 18:22 10%   ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
@ 2007-02-08 13:39 10%     ` Stephen Leake
  0 siblings, 0 replies; 94+ results
From: Stephen Leake @ 2007-02-08 13:39 UTC (permalink / raw)


"Jeffrey R. Carter" <jrcarter@acm.org> writes:

> Ludovic Brenta wrote:
>> Ada.Characters.Latin_1.HT (for Horizontal Tab).
>
> Or Character'Val (9). Or Character'Succ (Ada.Characters.Latin_1.BS).
> But Latin_1 is the better way.

Or ASCII.HT.

ASCII is labeled "Obsolete", but it will never go away; every Ada
compiler implements it. Maybe I'm just old-fashioned, but I prefer it
over Latin_1 for things like this :).

-- 
-- Stephe



^ permalink raw reply	[relevance 10%]

* Re: Ada.Containers.Doubly_Linked_Lists
       [not found]     <mailman.75.1170828524.18371.comp.lang.ada@ada-france.org>
  2007-02-07  7:16 10% ` Ada.Containers.Doubly_Linked_Lists Niklas Holsti
@ 2007-02-08 13:37 10% ` Stephen Leake
  1 sibling, 0 replies; 94+ results
From: Stephen Leake @ 2007-02-08 13:37 UTC (permalink / raw)


"Carroll, Andrew" <andrew.carroll@okstate.edu> writes:

> Okay, got the packages "instantiated" and all that and successfully
> appended an "element" to my list. How do I print the length to the
> console?
>  
> Where is count_type defined?

Your IDE should be able to tell you that, if the program is compiled.

In Emacs, put the cursor on the identifier "Count_Type", and hit C-c
C-d.

AdaGide can do the same thing, probably with some mouse click.

-- 
-- Stephe



^ permalink raw reply	[relevance 10%]

* Re: Ada.Containers.Doubly_Linked_Lists
  2007-02-07 18:19 10% ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
@ 2007-02-08 10:44 10%   ` Alex R. Mosteo
  0 siblings, 0 replies; 94+ results
From: Alex R. Mosteo @ 2007-02-08 10:44 UTC (permalink / raw)


Jeffrey R. Carter wrote:

> Carroll, Andrew wrote:
>> 
>> I found a way to output the Count_Type that was different than your way
>> but I like yours.  I didn't realize that the 'Image "thing" applies to
>> all integer types.  What is the 'Image "thing" called again...?
> 
> The 'Image attribute is defined for all numeric types and all
> enumeration types.

Also check its 'Value companion... 




^ permalink raw reply	[relevance 10%]

* Re: Ada.Containers.Doubly_Linked_Lists
  2007-02-07 15:06 10% ` Ada.Containers.Doubly_Linked_Lists Ludovic Brenta
@ 2007-02-07 18:22 10%   ` Jeffrey R. Carter
  2007-02-08 13:39 10%     ` Ada.Containers.Doubly_Linked_Lists Stephen Leake
  0 siblings, 1 reply; 94+ results
From: Jeffrey R. Carter @ 2007-02-07 18:22 UTC (permalink / raw)


Ludovic Brenta wrote:
> 
> Ada.Characters.Latin_1.HT (for Horizontal Tab).

Or Character'Val (9). Or Character'Succ (Ada.Characters.Latin_1.BS). But 
Latin_1 is the better way.

-- 
Jeff Carter
"No one is to stone anyone until I blow this whistle,
do you understand? Even--and I want to make this
absolutely clear--even if they do say, 'Jehovah.'"
Monty Python's Life of Brian
74



^ permalink raw reply	[relevance 10%]

* Re: Ada.Containers.Doubly_Linked_Lists
  2007-02-07 14:52 10% Ada.Containers.Doubly_Linked_Lists Carroll, Andrew
  2007-02-07 15:06 10% ` Ada.Containers.Doubly_Linked_Lists Ludovic Brenta
@ 2007-02-07 18:19 10% ` Jeffrey R. Carter
  2007-02-08 10:44 10%   ` Ada.Containers.Doubly_Linked_Lists Alex R. Mosteo
  1 sibling, 1 reply; 94+ results
From: Jeffrey R. Carter @ 2007-02-07 18:19 UTC (permalink / raw)


Carroll, Andrew wrote:
> 
> I found a way to output the Count_Type that was different than your way
> but I like yours.  I didn't realize that the 'Image "thing" applies to
> all integer types.  What is the 'Image "thing" called again...?

The 'Image attribute is defined for all numeric types and all 
enumeration types.

-- 
Jeff Carter
"No one is to stone anyone until I blow this whistle,
do you understand? Even--and I want to make this
absolutely clear--even if they do say, 'Jehovah.'"
Monty Python's Life of Brian
74



^ permalink raw reply	[relevance 10%]

* Re: Ada.Containers.Doubly_Linked_Lists
  2007-02-07 14:52 10% Ada.Containers.Doubly_Linked_Lists Carroll, Andrew
@ 2007-02-07 15:06 10% ` Ludovic Brenta
  2007-02-07 18:22 10%   ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
  2007-02-07 18:19 10% ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
  1 sibling, 1 reply; 94+ results
From: Ludovic Brenta @ 2007-02-07 15:06 UTC (permalink / raw)


Carroll, Andrew writes:
> It's been over a year since I've even looked at an Ada program.  I
> forgot pretty much everything.
>
> I found a way to output the Count_Type that was different than your way
> but I like yours.  I didn't realize that the 'Image "thing" applies to
> all integer types.  What is the 'Image "thing" called again...?

An attribute.

> Next question.  How do I output a tab character?
> I don't see a constant for that in text_io.  

Ada.Characters.Latin_1.HT (for Horizontal Tab).

-- 
Ludovic Brenta.



^ permalink raw reply	[relevance 10%]

* Ada.Containers.Doubly_Linked_Lists
@ 2007-02-07 14:52 10% Carroll, Andrew
  2007-02-07 15:06 10% ` Ada.Containers.Doubly_Linked_Lists Ludovic Brenta
  2007-02-07 18:19 10% ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
  0 siblings, 2 replies; 94+ results
From: Carroll, Andrew @ 2007-02-07 14:52 UTC (permalink / raw)
  To: comp.lang.ada

It's been over a year since I've even looked at an Ada program.  I
forgot pretty much everything.

I found a way to output the Count_Type that was different than your way
but I like yours.  I didn't realize that the 'Image "thing" applies to
all integer types.  What is the 'Image "thing" called again...?

Next question.  How do I output a tab character?
I don't see a constant for that in text_io.  


Andrew 



^ permalink raw reply	[relevance 10%]

* Re: Ada.Containers.Doubly_Linked_Lists
       [not found]     <mailman.75.1170828524.18371.comp.lang.ada@ada-france.org>
@ 2007-02-07  7:16 10% ` Niklas Holsti
  2007-02-08 13:37 10% ` Ada.Containers.Doubly_Linked_Lists Stephen Leake
  1 sibling, 0 replies; 94+ results
From: Niklas Holsti @ 2007-02-07  7:16 UTC (permalink / raw)


Carroll, Andrew wrote:
> Okay, got the packages "instantiated" and all that and
> successfully appended an "element" to my list.

Good!

> How do I print the length to the console?

Assuming your list package is named Thing_Lists and your list object is 
named Things, of type Thing_Lists.List:

    Ada.Text_IO.Put_Line (
         "The length is"
       & Ada.Containers.Count_Type'Image (Thing_Lists.Length (Things)));

> Where is count_type defined?

In the package Ada.Containers.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 10%]

* Ada.Containers.Doubly_Linked_Lists
@ 2007-02-06 14:40 10% Carroll, Andrew
  0 siblings, 0 replies; 94+ results
From: Carroll, Andrew @ 2007-02-06 14:40 UTC (permalink / raw)
  To: comp.lang.ada


Thanks all!





^ permalink raw reply	[relevance 10%]

* Re: Ada.Containers.Indefinite_Doubly_Linked_Lists
  @ 2007-02-05 20:39  7% ` Niklas Holsti
  0 siblings, 0 replies; 94+ results
From: Niklas Holsti @ 2007-02-05 20:39 UTC (permalink / raw)


Carroll, Andrew wrote:
> [ ... ]
> Package Attribute_List is new new
> Ada.Containers.Indefinite_Doubly_Linked_Lists (Attribute);
> 
> Type Table is record
> 	Name: String(50);
> 	Attributes:  Attribute_List;
                      ^^^^^^^^^^^^^^
Should be            Attribute_List.List;
because Attribute_List is a package that manages lists of Attributes, 
not a data type. The data type is Attribute_List.List.

> End record

> Package Table_List is new Ada.Containers.Indefinite_Doubly_Linked_Lists
> (Table);

I find it clearer to use names in plural form for packages that manage 
many objects of a given type. In this case I would use the name 
Attribute_Lists (not ..._List) for the package that manages lists of 
Attribute objects (each such list is an object of type 
Attribute_Lists.List). I would use the name Table_Lists for the package 
that manages lists of Table objects (each such list is an object of type 
Table_Lists.List).

The language-defined Ada packages use the same convention, for example 
Ada.Containers.Doubly_Linked_Lists (not ..._List). Of course you can use 
any names you like.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Doubly_Linked_Lists
  2007-02-04 22:08 19%   ` Ada.Containers.Doubly_Linked_Lists Ludovic Brenta
@ 2007-02-05 15:43 10%     ` Matthew Heaney
  0 siblings, 0 replies; 94+ results
From: Matthew Heaney @ 2007-02-05 15:43 UTC (permalink / raw)


On Feb 4, 5:08 pm, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
> If all you want is an unbounded string, just say
>
> package Lists_Of_Unbouned_Strings is
>    new Ada.Containers.Doubly_Linked_Lists
>      (Element_Type => Ada.Strings.Unbounded.Unbounded_Strings);
>
> L : Lists_Of_Unbouned_Strings.List;

A cleaner way to do this (that avoids having to use type
Unbounded_String) is:

package String_Lists is
  new Ada.Containers.Indefinite_Doubly_Linked_Lists (String);

procedure Op (L : String_Lists.List) is
begin
  L.Append ("Hello, World!");
end;




^ permalink raw reply	[relevance 10%]

* Re: Ada.Containers.Doubly_Linked_Lists
       [not found]     <mailman.69.1170624131.18371.comp.lang.ada@ada-france.org>
  2007-02-04 21:35 19% ` Ada.Containers.Doubly_Linked_Lists Niklas Holsti
@ 2007-02-05  4:03 18% ` Jeffrey R. Carter
  1 sibling, 0 replies; 94+ results
From: Jeffrey R. Carter @ 2007-02-05  4:03 UTC (permalink / raw)


Carroll, Andrew wrote:
>  
> Okay, so, just out of curiosity, what do I do if I need the Node_type 
> within Ada.Containers.Doubly_Linked_Lists to have an additional 
> "attribute"?  So instead of just having
>  
> type Node_Type is limited record
>  Element : Element_Access;
>  Next : Node_Access;
>  Prev : Node_Access;
> end record;

There is nothing named Node_Type in Ada.Containers.Doubly_Linked_Lists. 
See ARM-0X A.18.3 for the definition of this generic package:

http://www.adaic.org/standards/05rm/html/RM-A-18-3.html

An implementation may have something named Node_Type, but that would not 
be in the visible part of the specification, and so unavailable to you 
as a client of the generic or instantiations of it. Another 
implementation may be completely different, so relying on information 
about the implementation would be completely non-portable.

-- 
Jeff Carter
"Now go away or I shall taunt you a second time."
Monty Python & the Holy Grail
07



^ permalink raw reply	[relevance 18%]

* Re: Ada.Containers.Doubly_Linked_Lists
  2007-02-04 21:35 19% ` Ada.Containers.Doubly_Linked_Lists Niklas Holsti
@ 2007-02-04 22:08 19%   ` Ludovic Brenta
  2007-02-05 15:43 10%     ` Ada.Containers.Doubly_Linked_Lists Matthew Heaney
  0 siblings, 1 reply; 94+ results
From: Ludovic Brenta @ 2007-02-04 22:08 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@nospam.please> writes:

> Carroll, Andrew wrote:
>> Ahhhhh, I see.
>
> (Please quote a bit of the post to which you are replying so that the
> context of your "Ahhhhh" is clearer :-)
>
>> Okay, so, just out of curiosity, what do I do if I need the
>> Node_type within Ada.Containers.Doubly_Linked_Lists to
>> have an additional "attribute"?
>
> What Node_Type? Are you peeking at the *private* part of
> Ada.Containers.Doubly_Linked_Lists, or even at the source-code of the
> body of the generic? That's useless because you can't access the
> private stuff or the stuff in the body.
>
> Whatever you want to keep in your list, put it in your Element_Type,
> the type that you use to instantiate Doubly_Linked_Lists. For example,
> make it a record type and put in whatever components you need.

And, if Niklas' answer was unclear, do not add Prev or Next to your
Element_Type; it is the generic linked list's job to add and manage
them.  If all you want is an unbounded string, just say

package Lists_Of_Unbouned_Strings is
   new Ada.Containers.Doubly_Linked_Lists
     (Element_Type => Ada.Strings.Unbounded.Unbounded_Strings);

L : Lists_Of_Unbouned_Strings.List;

and off you go.

-- 
Ludovic Brenta.



^ permalink raw reply	[relevance 19%]

* Re: Ada.Containers.Doubly_Linked_Lists
       [not found]     <mailman.69.1170624131.18371.comp.lang.ada@ada-france.org>
@ 2007-02-04 21:35 19% ` Niklas Holsti
  2007-02-04 22:08 19%   ` Ada.Containers.Doubly_Linked_Lists Ludovic Brenta
  2007-02-05  4:03 18% ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
  1 sibling, 1 reply; 94+ results
From: Niklas Holsti @ 2007-02-04 21:35 UTC (permalink / raw)


Carroll, Andrew wrote:
> Ahhhhh, I see.

(Please quote a bit of the post to which you are replying so that the 
context of your "Ahhhhh" is clearer :-)

> Okay, so, just out of curiosity, what do I do if I need the
> Node_type within Ada.Containers.Doubly_Linked_Lists to
> have an additional "attribute"? 

What Node_Type? Are you peeking at the *private* part of 
Ada.Containers.Doubly_Linked_Lists, or even at the source-code of the 
body of the generic? That's useless because you can't access the private 
stuff or the stuff in the body.

Whatever you want to keep in your list, put it in your Element_Type, the 
type that you use to instantiate Doubly_Linked_Lists. For example, make 
it a record type and put in whatever components you need.

--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 19%]

* Re: Ada.Containers.Doubly_Linked_Lists
       [not found]     <mailman.67.1170570920.18371.comp.lang.ada@ada-france.org>
  2007-02-04  8:10 20% ` Ada.Containers.Doubly_Linked_Lists Niklas Holsti
@ 2007-02-04 21:05 21% ` Jeffrey R. Carter
  1 sibling, 0 replies; 94+ results
From: Jeffrey R. Carter @ 2007-02-04 21:05 UTC (permalink / raw)


Carroll, Andrew wrote:
>  
> I would like to understand how to use the 
> Ada.Containers.Doubly_Linked_Lists  package.  After I with 
> Ada.Containers.Doubly_Linked_Lists and then declare a variable x: 
> Ada.Containers.Doubly_Linked_Lists.List I get the error:
>  
> invalid prefix in selected component "doubly_linked_lists".

Ada.Containers.Doubly_Linked_Lists is not a package. It's a generic. A 
generic is like a template; you use it to create things (in this case, 
packages); this is called instantiation:

package P is new Ada.Containers.Doubly_Linked_Lists
    (Element_Type => Whatever, "=" => Some_Function);

Now P is a package, and may be used as any other package:

V : P.List;

-- 
Jeff Carter
"Now go away or I shall taunt you a second time."
Monty Python & the Holy Grail
07



^ permalink raw reply	[relevance 21%]

* Re: Ada.Containers.Doubly_Linked_Lists
       [not found]     <mailman.67.1170570920.18371.comp.lang.ada@ada-france.org>
@ 2007-02-04  8:10 20% ` Niklas Holsti
  2007-02-04 21:05 21% ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
  1 sibling, 0 replies; 94+ results
From: Niklas Holsti @ 2007-02-04  8:10 UTC (permalink / raw)


Carroll, Andrew wrote:
> Hello,
>  
> I would like to understand how to use the Ada.Containers.Doubly_Linked_Lists
> package.  After I with Ada.Containers.Doubly_Linked_Lists and then
> declare a variable x: Ada.Containers.Doubly_Linked_Lists.List I get
> the error:
>  
> invalid prefix in selected component "doubly_linked_lists".
>  
> So, what I'm saying here is that I have no clue how to use the
> Ada.Containers.Doubly_Linked_Lists package and I'm hoping that
> someone here can show me how to use it.

The packages in Ada.Containers are "generic" packages, so you first have 
to make an "instance" of Doubly_Linked_Lists before your program can 
declare list variables. When you make an instance, you specify which 
type of elements the list can hold (Element_Type) and how to compare two 
elements for equality (the "=" operator for Element_Type).

See http://en.wikibooks.org/wiki/Ada_Programming/Generics for 
explanation and examples of generic packages, and 
http://www.adaic.com/standards/05rat/html/Rat-8.html for specific advice 
on Ada.Containers.

For example, here is how to make a package that manages lists of Integers:

    with Ada.Containers.Doubly_Linked_Lists;
    ...

    package Integer_Lists is
       new Ada.Containers.Doubly_Linked_Lists (
          Element_Type => Integer);

(I did not give any actual for the formal "=" operator because it 
defaults to the predefined "=" for comparing Integers.)

And here is how to declare a variable that holds a list of Integers:

    Ints : Integer_Lists.List;

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 20%]

* Re: generic question
  @ 2006-11-19 19:17  9% ` Ludovic Brenta
  0 siblings, 0 replies; 94+ results
From: Ludovic Brenta @ 2006-11-19 19:17 UTC (permalink / raw)


markww writes:
>     type NODE_REC is
>         record
>             unknown_data_type : generic;  -- not sure how to express
> this in ada
>             Next_Node : NODE_REC_PTR;
>             Prev_Node : NODE_REC_PTR;
>       end record;

generic
   type T is private;
package P is
   type Node;
   type Node_Ptr is access Node;
   type Node is record
      Data : T;
      Prev, Next : Node_Ptr;
   end record;
end P;

HTH

See also the predefined containers, in particular
Ada.Containers.Doubly_Linked_Lists [1]

[1] http://www.adaic.com/standards/05rm/html/RM-A-18-3.html

-- 
Ludovic Brenta.



^ permalink raw reply	[relevance 9%]

* Re: Ada 2005: Attempting to create a useful subject/observer pattern
  2006-10-24 21:01  6% Ada 2005: Attempting to create a useful subject/observer pattern Lucretia
@ 2006-10-25  8:22  0% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 94+ results
From: Dmitry A. Kazakov @ 2006-10-25  8:22 UTC (permalink / raw)


On 24 Oct 2006 14:01:50 -0700, Lucretia wrote:

> Like the subject states, I'm trying to implement a usable
> subject/observer pattern which is an extension of the GoF original and
> something closer to Java's Listeners.

yuck...

> The idea was to use the code in a
> gui library. After talking on IRC (#Ada) and working with the guys
> there (Baldrick ;D), it was noted that GNAT is flawed in it's
> interfaces, but I'd like to know if anyone here can indicate whether
> the code is wrong and GNAT should accept it or not.

I cannot comment on compiler bugs, I am not a language lawyer. So I only
comment on to the code.

> I'm using FSF GNAT from GCC 4.1.1 and the errors are:
> 
> gnatmake -gnat05 test_observers2.adb
> gcc -c -gnat05 test_observers2.adb
> test_observers2.adb:16:34: (Ada 2005) interface subprogram "Update"
> must be abstract or null
> test_observers2.adb:23:31: expected private type "Event" defined at
> events.ads:5test_observers2.adb:23:31: found private type "Mouse_Event"
> defined at mouse_events.ads:5
> my_observer.ads:10:03: (Ada 2005) interface subprogram "On_Mouse_Click"
> must be abstract or null
> subjects.ads:15:10: (Ada 2005) interface subprogram "Update" must be
> abstract or null
> subjects.ads:15:20: operation can be dispatching in only one type
> gnatmake: "test_observers2.adb" compilation error
> 
> All code below is GPL'd and can be gnatchopped:
> 
> with Ada.Finalization;
> package Events is
>   type Event is new Ada.Finalization.Controlled with private;
> private
>   type Event is new Ada.Finalization.Controlled with null record;
> end Events;
>
> with Events; 
> package Mouse_Events is
>   type Mouse_Event is new Events.Event with private;
> private 
>   type Mouse_Event is new Events.Event with null record;
> end Mouse_Events;
>
> with Mouse_Events;
> with Observers; 
> package Mouse_Observers is
>   type Mouse_Observer is interface and Observers.Observer;
>   procedure On_Mouse_Click(Self : in Mouse_Observer; Event : in
> Mouse_Events.Mouse_Event) is null;

I suppose this should be:

procedure On_Mouse_Click
          (  Self  : in Mouse_Observer;
             Event : in Mouse_Events.Mouse_Event'Class
          )  is null;

> end Mouse_Observers;
>
> with Ada.TexT_IO; 
> package body My_Observer is
> --  procedure Update(Self : in My_Observer_Type) is
> --  begin
> --    Ada.TexT_IO.Put_Line("[My_Observer.Update]");
> --  end Update;
> 
>   procedure On_Mouse_Click(Self : in Mouse_Observer; Event : in
> Mouse_Events.Mouse_Event) is
>   begin
>     Ada.TexT_IO.Put_Line("[My_Observer.On_Mouse_Click]");
>   end On_Mouse_Click;
> end My_Observer;
>
> with Mouse_Observers;
> with Mouse_Events;
> package My_Observer is
>   type My_Observer_Type is new Mouse_Observers.Mouse_Observer with
> private; 
>   overriding
> --  procedure Update(Self : in My_Observer_Type);
>   procedure On_Mouse_Click(Self : in Mouse_Observers.Mouse_Observer;
> Event : in Mouse_Events.Mouse_Event);
> 
> private
>   type My_Observer_Type is new Mouse_Observers.Mouse_Observer with null
> record;
> end My_Observer;
>
> package Observers is 
>   type Observer is interface;

Why don't you define abstract Notify on Observer? Why Observer need to be
an interface? What does guarantee detachment of observers upon
finalization?

>   type Observer_Access is access all Observer'Class;
> end Observers;
>
> with Observers;
> 
> package body Subjects is
>   use type Observer_Lists.Cursor;
>   -- Add an observer to this subject's internal list.
>   procedure Attach(Self : in out Subject'Class; Observer : access
> Observers.Observer'Class) is
>   begin
>     Self.Observer_List.Append(New_Item =>
> Observers.Observer_Access(Observer));
>   end Attach;
> 
>   -- Remove an observer from this subject's internal list.
>   procedure Detach(Self : in out Subject'Class; Observer : access
> Observers.Observer'Class) is
> 
>     Position : Observer_Lists.Cursor :=
> Self.Observer_List.Find(Observers.Observer_Access(Observer));
>   begin
>     if Position /= Observer_Lists.No_Element then
>       Self.Observer_List.Delete(Position);
>     end if;
>   end Detach;
> 
>   -- Notify all observers who are monitoring this subject that
> something has happened.
>   procedure Notify(Self : in Subject; Event : in Events.Event) is
> 
>     Current : Observer_Lists.Cursor := Self.Observer_List.First;
>   begin
>     while Current /= Observer_Lists.No_Element loop
>       if Observer_Lists.Element(Current)'Class = Matching_Event'Class
> then

This should be something like:

if Observer_Lists.Element (Current) in Matching_Event'Class then

However, I would not use a design that queues events to [ultimate]
observers. Rather I would queue observers to the event sources. That would
save me event filtering issue, as well as crude emulations of multiple
dispatch like you tried above.

>         Update(Observer_Lists.Element(Current), Event);
>         --Observer_Lists.Element(Current).Update;
>         Current := Observer_Lists.Next(Current);
>       end if;
>     end loop;
>   end Notify;

There is a big problem with traversing the list of observers, while calling
notifications. If some of the notification causes a list change? This is a
no-no with Ada.Containers. So you have to undertake some actions to ensure
that this would never happen. Unfortunately it is necessary to happen. I
usually add some parameters to Update, to allow the subscribers to postpone
some notifications from the callback. But this is a complex issue for such
a small example.

> --  function Equals(Left, Right : access Observers.Observer) return
> Boolean is
>   function Equals(Left, Right : Observers.Observer_Access) return
> Boolean is
>     use type Observers.Observer_Access;
>   begin
>     if Left = Right then
>       return True;
>     end if;
>     return False;
>   end Equals;

My rule of thumb: If objects have referential identity => they have to be
limited. So I would make Observer Limited_Controlled, if I wished to
compare pointers to them.

> end Subjects;
> with Observers;
> with Ada.Containers.Doubly_Linked_Lists;
> with Ada.Finalization;
> with Events;
> 
> package Subjects is
> 
>   type Subject is new Ada.Finalization.Limited_Controlled with private;
> 
>   procedure Attach(Self : in out Subject'Class; Observer : access
> Observers.Observer'Class);
>   procedure Detach(Self : in out Subject'Class; Observer : access
> Observers.Observer'Class);
> 
>   generic
>     type Matching_Event is new Events.Event with private;
>     with procedure Update(Self : in Observers.Observer; Event : in
> Events.Event) is abstract;

   ... Matching_Event'Class, I suppose.

>   procedure Notify(Self : in Subject; Event : in Events.Event);

procedure Notify(Self : in Subject'Class; Event : in Events.Event'Class);

Another empirical rule: if a subprogram takes tagged arguments and is not
primitive (or maybe located in a body), then it should be class-wide.

And, well, generics to hide type casting ... 

> private
> 
>   function Equals(Left, Right : Observers.Observer_Access) return
> Boolean;
> 
>   package Observer_Lists is new
> Ada.Containers.Doubly_Linked_Lists(Observers.Observer_Access, Equals);
> 
>   type Subject is new Ada.Finalization.Limited_Controlled with
>     record
>       Observer_List : Observer_Lists.List;
>     end record;
> 
> end Subjects;
> with My_Observer;
> with Subjects;
> --with Observers;
> with Mouse_Events;
> 
> procedure Test_Observers2 is
> 
> --  Obs     : Observers.Observer_Access := new
> My_Observer.My_Observer_Type;
> --  Obs     : access Observers.Observer := new
> My_Observer.My_Observer_Type;
>   Obs         : aliased My_Observer.My_Observer_Type;
>   Subject     : Subjects.Subject;
>   Mouse_Event : Mouse_Events.Mouse_Event;
> 
>   procedure Notify_Mouse_Click is new Subjects.Notify(
>     Matching_Event => Mouse_Events.Mouse_Event,
>     Update         => My_Observer.On_Mouse_Click);
> 
> begin
>   Subject.Attach(Obs'Access);
> --  Subject.Attach(Observers.Observer(Obs)'Access);
> --  Subject.Notify;
>   Notify_Mouse_Click(Subject, Mouse_Event);
>   
> end Test_Observers2;

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



^ permalink raw reply	[relevance 0%]

* Ada 2005: Attempting to create a useful subject/observer pattern
@ 2006-10-24 21:01  6% Lucretia
  2006-10-25  8:22  0% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 94+ results
From: Lucretia @ 2006-10-24 21:01 UTC (permalink / raw)


Hi,

Like the subject states, I'm trying to implement a usable
subject/observer pattern which is an extension of the GoF original and
something closer to Java's Listeners. The idea was to use the code in a
gui library. After talking on IRC (#Ada) and working with the guys
there (Baldrick ;D), it was noted that GNAT is flawed in it's
interfaces, but I'd like to know if anyone here can indicate whether
the code is wrong and GNAT should accept it or not.

I'm using FSF GNAT from GCC 4.1.1 and the errors are:

gnatmake -gnat05 test_observers2.adb
gcc -c -gnat05 test_observers2.adb
test_observers2.adb:16:34: (Ada 2005) interface subprogram "Update"
must be abstract or null
test_observers2.adb:23:31: expected private type "Event" defined at
events.ads:5test_observers2.adb:23:31: found private type "Mouse_Event"
defined at mouse_events.ads:5
my_observer.ads:10:03: (Ada 2005) interface subprogram "On_Mouse_Click"
must be abstract or null
subjects.ads:15:10: (Ada 2005) interface subprogram "Update" must be
abstract or null
subjects.ads:15:20: operation can be dispatching in only one type
gnatmake: "test_observers2.adb" compilation error

Thanks,
Luke.

All code below is GPL'd and can be gnatchopped:

with Ada.Finalization;

package Events is

  type Event is new Ada.Finalization.Controlled with private;

private

  type Event is new Ada.Finalization.Controlled with null record;

end Events;
with Events;

package Mouse_Events is

  type Mouse_Event is new Events.Event with private;

private

  type Mouse_Event is new Events.Event with null record;

end Mouse_Events;
with Mouse_Events;
with Observers;

package Mouse_Observers is

  type Mouse_Observer is interface and Observers.Observer;

  procedure On_Mouse_Click(Self : in Mouse_Observer; Event : in
Mouse_Events.Mouse_Event) is null;

end Mouse_Observers;
with Ada.TexT_IO;

package body My_Observer is

--  procedure Update(Self : in My_Observer_Type) is

--  begin

--    Ada.TexT_IO.Put_Line("[My_Observer.Update]");

--  end Update;

  procedure On_Mouse_Click(Self : in Mouse_Observer; Event : in
Mouse_Events.Mouse_Event) is

  begin

    Ada.TexT_IO.Put_Line("[My_Observer.On_Mouse_Click]");

  end On_Mouse_Click;

end My_Observer;
with Mouse_Observers;
with Mouse_Events;

package My_Observer is

  type My_Observer_Type is new Mouse_Observers.Mouse_Observer with
private;

  overriding
--  procedure Update(Self : in My_Observer_Type);
  procedure On_Mouse_Click(Self : in Mouse_Observers.Mouse_Observer;
Event : in Mouse_Events.Mouse_Event);

private

  type My_Observer_Type is new Mouse_Observers.Mouse_Observer with null
record;

end My_Observer;
package Observers is

  type Observer is interface;
  type Observer_Access is access all Observer'Class;

end Observers;
with Observers;

package body Subjects is

  use type Observer_Lists.Cursor;

  -- Add an observer to this subject's internal list.
  procedure Attach(Self : in out Subject'Class; Observer : access
Observers.Observer'Class) is

  begin

    Self.Observer_List.Append(New_Item =>
Observers.Observer_Access(Observer));

  end Attach;


  -- Remove an observer from this subject's internal list.
  procedure Detach(Self : in out Subject'Class; Observer : access
Observers.Observer'Class) is

    Position : Observer_Lists.Cursor :=
Self.Observer_List.Find(Observers.Observer_Access(Observer));

  begin

    if Position /= Observer_Lists.No_Element then

      Self.Observer_List.Delete(Position);

    end if;

  end Detach;


  -- Notify all observers who are monitoring this subject that
something has happened.
  procedure Notify(Self : in Subject; Event : in Events.Event) is

    Current : Observer_Lists.Cursor := Self.Observer_List.First;

  begin

    while Current /= Observer_Lists.No_Element loop

      if Observer_Lists.Element(Current)'Class = Matching_Event'Class
then

        Update(Observer_Lists.Element(Current), Event);

        --Observer_Lists.Element(Current).Update;

        Current := Observer_Lists.Next(Current);

      end if;

    end loop;

  end Notify;


--  function Equals(Left, Right : access Observers.Observer) return
Boolean is
  function Equals(Left, Right : Observers.Observer_Access) return
Boolean is

    use type Observers.Observer_Access;

  begin

    if Left = Right then

      return True;

    end if;

    return False;

  end Equals;

end Subjects;
with Observers;
with Ada.Containers.Doubly_Linked_Lists;
with Ada.Finalization;
with Events;

package Subjects is

  type Subject is new Ada.Finalization.Limited_Controlled with private;

  procedure Attach(Self : in out Subject'Class; Observer : access
Observers.Observer'Class);
  procedure Detach(Self : in out Subject'Class; Observer : access
Observers.Observer'Class);

  generic
    type Matching_Event is new Events.Event with private;
    with procedure Update(Self : in Observers.Observer; Event : in
Events.Event) is abstract;
  procedure Notify(Self : in Subject; Event : in Events.Event);

private

  function Equals(Left, Right : Observers.Observer_Access) return
Boolean;

  package Observer_Lists is new
Ada.Containers.Doubly_Linked_Lists(Observers.Observer_Access, Equals);

  type Subject is new Ada.Finalization.Limited_Controlled with
    record
      Observer_List : Observer_Lists.List;
    end record;

end Subjects;
with My_Observer;
with Subjects;
--with Observers;
with Mouse_Events;

procedure Test_Observers2 is

--  Obs     : Observers.Observer_Access := new
My_Observer.My_Observer_Type;
--  Obs     : access Observers.Observer := new
My_Observer.My_Observer_Type;
  Obs         : aliased My_Observer.My_Observer_Type;
  Subject     : Subjects.Subject;
  Mouse_Event : Mouse_Events.Mouse_Event;

  procedure Notify_Mouse_Click is new Subjects.Notify(
    Matching_Event => Mouse_Events.Mouse_Event,
    Update         => My_Observer.On_Mouse_Click);

begin

  Subject.Attach(Obs'Access);
--  Subject.Attach(Observers.Observer(Obs)'Access);
--  Subject.Notify;
  Notify_Mouse_Click(Subject, Mouse_Event);
  
end Test_Observers2;




^ permalink raw reply	[relevance 6%]

* Re: Ada 2005 box (<>) rules in default values
  2006-01-17  8:31  5% Ada 2005 box (<>) rules in default values Alex R. Mosteo
@ 2006-01-17 13:35  0% ` ME
  0 siblings, 0 replies; 94+ results
From: ME @ 2006-01-17 13:35 UTC (permalink / raw)


When will a Ada 2005 compiler become publicly available i.e. gnat 16.0P?
"Alex R. Mosteo" <devnull@mailinator.com> wrote in message 
news:43CCAB76.6050907@mailinator.com...
> Hi all,
>
> I have a doubt with the box operator as newly introduced in Ada 2005 to 
> allow in place initialization of limited types. I'm not sure of all the 
> details so anything I say can be wrong; if so please correct me.
>
> My understanding is that you use the <> value to denote the default value 
> of a field in, for example a (limited or not) record:
>
> Blah : constant Thing :=
>  (First_Component  => 3,
>          Second_Component => 4,
>          others => <>);
>
> This actually compiles in GNAT GAP/GPL, but there's a thing happening that 
> I don't know if it's that it isn't still completely implemented in Gnat, 
> or is the expected behavior.
>
> Say, for example, that Thing above is declared like:
>
> type Thing is record
>    First_Component  : Integer;
>    Second_Component : Integer;
>    Third_Component  : Integer := 5;
> end record;
>
> I'm finding that if I use the box as in the first example above, the third 
> component will not receive its default value from the type definition (5), 
> but will be uninitialized. I've noticed this because initializing types 
> like this:
>
> type Other_Thing is record
>     X : Integer;
>     L : List;
>     -- From some instantiation of Ada.Containers.Doubly_Linked_Lists
> end record;
>
> with
>
> Y : Other_Thing := (X => 5, others => <>);
>
> This initialization more often than not will have an invalid list (i.e. 
> not an empty list, but one with improper values that fails when used).
>
> I've read the Aggregates Issues in the "Gnat and Ada 2005" document, and 
> there the <> initializer is mentioned primarily in relation to limited 
> types. From that document I read:
>
> "The box notation ("<>") is now used to denote the default initialization 
> for a component of an aggregate, that is to say an invocation of the 
> initialization procedure for the component type."
>
> And
>
> "Note that the "others => <>" notation is allowed even when the associated 
> components are not of the same type. Its meaning is as follows: if a 
> component has a default expression in the record type, the expression is 
> used; otherwise, the normal default initialization for its type is used."
>
> From these paragraphs I understand that Gnat is not implementing correctly 
> that feature for the moment. So I ask if you knowledgeable lot agree with 
> my impression. (A pointer to the amendment dealing with this will also be 
> welcome). 





^ permalink raw reply	[relevance 0%]

* Ada 2005 box (<>) rules in default values
@ 2006-01-17  8:31  5% Alex R. Mosteo
  2006-01-17 13:35  0% ` ME
  0 siblings, 1 reply; 94+ results
From: Alex R. Mosteo @ 2006-01-17  8:31 UTC (permalink / raw)


Hi all,

I have a doubt with the box operator as newly introduced in Ada 2005 to 
allow in place initialization of limited types. I'm not sure of all the 
details so anything I say can be wrong; if so please correct me.

My understanding is that you use the <> value to denote the default 
value of a field in, for example a (limited or not) record:

Blah : constant Thing :=
  	(First_Component  => 3,
          Second_Component => 4,
          others => <>);

This actually compiles in GNAT GAP/GPL, but there's a thing happening 
that I don't know if it's that it isn't still completely implemented in 
Gnat, or is the expected behavior.

Say, for example, that Thing above is declared like:

type Thing is record
    First_Component  : Integer;
    Second_Component : Integer;
    Third_Component  : Integer := 5;
end record;

I'm finding that if I use the box as in the first example above, the 
third component will not receive its default value from the type 
definition (5), but will be uninitialized. I've noticed this because 
initializing types like this:

type Other_Thing is record
     X : Integer;
     L : List;
     -- From some instantiation of Ada.Containers.Doubly_Linked_Lists
end record;

with

Y : Other_Thing := (X => 5, others => <>);

This initialization more often than not will have an invalid list (i.e. 
not an empty list, but one with improper values that fails when used).

I've read the Aggregates Issues in the "Gnat and Ada 2005" document, and 
there the <> initializer is mentioned primarily in relation to limited 
types. From that document I read:

"The box notation ("<>") is now used to denote the default 
initialization for a component of an aggregate, that is to say an 
invocation of the initialization procedure for the component type."

And

"Note that the "others => <>" notation is allowed even when the 
associated components are not of the same type. Its meaning is as 
follows: if a component has a default expression in the record type, the 
expression is used; otherwise, the normal default initialization for its 
type is used."

 From these paragraphs I understand that Gnat is not implementing 
correctly that feature for the moment. So I ask if you knowledgeable lot 
agree with my impression. (A pointer to the amendment dealing with this 
will also be welcome).



^ permalink raw reply	[relevance 5%]

* Re: GCC 4.0 Ada.Containers Cursor danger.
  @ 2005-07-09 14:20  6%                   ` Matthew Heaney
  0 siblings, 0 replies; 94+ results
From: Matthew Heaney @ 2005-07-09 14:20 UTC (permalink / raw)


"Dmitriy Anisimkov" <anisimkov@yahoo.com> writes:

> Me, not. 99.9 would be enought. If you sure thar cursors would be
> checked in the coming Ada 200X, i'm quiet.

I'm working on the lists right now, so I modified your original example
as follows:

procedure Test_Dangling is
   package Integer_Lists is
      new Ada.Containers.Doubly_Linked_Lists (Integer);
   use Integer_Lists;

   L : List;
   C, C2 : Cursor;
begin
   L.Append (1);
   L.Insert (No_Element, 2, C);
   L.Append (3);

   C2 := L.Find (2);
   L.Delete (C2);

   Replace_Element (C, By => -2);  -- dangling reference
end;

I added some logic to detect dangling cursors, and when I run the
program above I get this output:

raised SYSTEM.ASSERTIONS.ASSERT_FAILURE : bad cursor in Replace_Element

The extra check is inside a pragma Assert, so you can choose to enable
it or not.

To make this work, I set the Next and Prev pointers of the internal
storage node to point to the node itself, just before the node is
deallocated.  In the GCC implementation, a linked list node never points
to itself, so I know that if a node pointer of a node has the node as
its value, then something must be wrong.

For the indefinite list, the element is designated by a pointer, which
can never be null.  When a node is deallocated, I set the element
pointer to null (that's sort of true anyway, since I must also
deallocate the element), and then check for a null element pointer
during cursor manipulation.

-Matt



^ permalink raw reply	[relevance 6%]

* Re: Memory leak - What the ...?
  @ 2004-10-12 15:07  7% ` Alex R. Mosteo
  0 siblings, 0 replies; 94+ results
From: Alex R. Mosteo @ 2004-10-12 15:07 UTC (permalink / raw)


Well, I have collected all the code snippets which use Udp_Message.
This is part of an UDP bandwidth throttling mechanism, here stripped
to only leave the relevant parts. I can't reproduce it with a small
test case. I can't see anything wrong in this code neither. I'll try
with Valgrind when I get back to my linux PC, but I feel unsuccesfull.

I've placed counters in the Udp_Message type that show that there
aren't leaked objects. The leak affects only the Data buffers, not the
whole objects.

Thanks everyone for your time. Code follows.

package Udp_Msgs_List is new Ada.Containers.Doubly_Linked_Lists (
   Udp_Message);

Udp_Msgs : Udp_Msgs_List.List;

-- Packet creation: --------------------
   Udp_message_list.Prepend (
      Udp_msgs,
      Create (Buffer (1 .. Last), Packet.Destination));
----------------------------------------

-- Sending -----------------------------
-- This is called periodically following some throttling rules.
---------------------------------------------------------------
   if Is_empty (Udp_msgs) then
      Next_sending := Clock + 1.0;
   else
      Msg := First_Element (Udp_msgs);
      Delete_first (Udp_msgs);

      Socket.Send (
         Udp_Socket,
         Msg.Data (Msg.Data'First .. Msg.Last),
         Last, -- Out value with the last sent component (should be
Msg.Last)
         Msg.Dest);

      -- Drop old packets:
      loop
         I := Udp_message_list.Last (Udp_msgs);
         exit when Is_empty (Udp_msgs) or else
            Now - Element (I).Date <=
            Globals.Options.G2_UdpOutboundTimeout;
         Delete_last (Udp_msgs); -- Drop it!
      end loop;
   end if;



^ permalink raw reply	[relevance 7%]

* Re: An improved Ada?
  @ 2004-09-28  5:45  8% ` Matthew Heaney
  0 siblings, 0 replies; 94+ results
From: Matthew Heaney @ 2004-09-28  5:45 UTC (permalink / raw)


jonas.nygren@telia.com (jn) writes:

> Here is my small example, based on the simset-library from Simula, not
> complete but it should be easy for you to fill out the rest:)

I don't understand what your problem is.  It looks like you need a list
whose elements have type Book_In_Shelf.  What's wrong with:

   package Book_Lists is
     new Ada.Containers.Doubly_Linked_Lists (Book_In_Shelf); 

If you need to move an element from one list onto another, then just use
the Splice operation for lists.

If you need a list whose elements have a class-wide type, then just use
the indefinite list.





^ permalink raw reply	[relevance 8%]

* Re: Feasibility of using Ada in new development
  @ 2004-08-25  8:12  8%         ` Martin Dowie
  0 siblings, 0 replies; 94+ results
From: Martin Dowie @ 2004-08-25  8:12 UTC (permalink / raw)


Adrian Hoe wrote:
> Eh... Ada does not have linked list support. And linked list is not
> equal to Access types. One can use Access type to develop a linked
> list library.

It does/will soon! See "Ada.Containers.Doubly_Linked_Lists" in AI-302.

<shameless_plug>
http://www.martin.dowie.btinternet.co.uk/
<\shameless_plug>

Cheers

-- Martin






^ permalink raw reply	[relevance 8%]

Results 1-94 of 94 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2004-08-23 18:27     Feasibility of using Ada in new development Robert Law
2004-08-24  4:13     ` Steve
2004-08-24 11:09       ` Phong Ho
2004-08-25  1:08         ` Puckdropper
2004-08-25  6:02           ` Adrian Hoe
2004-08-25  8:12  8%         ` Martin Dowie
2004-09-27 19:38     An improved Ada? jn
2004-09-28  5:45  8% ` Matthew Heaney
2004-10-10 21:33     Memory leak - What the ...? Alex R. Mosteo
2004-10-12 15:07  7% ` Alex R. Mosteo
2005-07-04 11:01     GCC 4.0 Ada.Containers Cursor danger Dmitriy Anisimkov
2005-07-05 14:51     ` Matthew Heaney
2005-07-05 17:11       ` Dmitriy Anisimkov
2005-07-06  7:30         ` Dmitry A. Kazakov
2005-07-06  7:50           ` Georg Bauhaus
2005-07-06 11:36             ` Dmitry A. Kazakov
2005-07-06 23:07               ` Randy Brukardt
2005-07-07 12:52                 ` Dmitriy Anisimkov
2005-07-07 19:47                   ` Randy Brukardt
2005-07-08  2:28                     ` Dmitriy Anisimkov
2005-07-09 14:20  6%                   ` Matthew Heaney
2006-01-17  8:31  5% Ada 2005 box (<>) rules in default values Alex R. Mosteo
2006-01-17 13:35  0% ` ME
2006-10-24 21:01  6% Ada 2005: Attempting to create a useful subject/observer pattern Lucretia
2006-10-25  8:22  0% ` Dmitry A. Kazakov
2006-11-19 18:03     generic question markww
2006-11-19 19:17  9% ` Ludovic Brenta
     [not found]     <mailman.67.1170570920.18371.comp.lang.ada@ada-france.org>
2007-02-04  8:10 20% ` Ada.Containers.Doubly_Linked_Lists Niklas Holsti
2007-02-04 21:05 21% ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
     [not found]     <mailman.69.1170624131.18371.comp.lang.ada@ada-france.org>
2007-02-04 21:35 19% ` Ada.Containers.Doubly_Linked_Lists Niklas Holsti
2007-02-04 22:08 19%   ` Ada.Containers.Doubly_Linked_Lists Ludovic Brenta
2007-02-05 15:43 10%     ` Ada.Containers.Doubly_Linked_Lists Matthew Heaney
2007-02-05  4:03 18% ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
2007-02-05 17:47     Ada.Containers.Indefinite_Doubly_Linked_Lists Carroll, Andrew
2007-02-05 20:39  7% ` Ada.Containers.Indefinite_Doubly_Linked_Lists Niklas Holsti
2007-02-06 14:40 10% Ada.Containers.Doubly_Linked_Lists Carroll, Andrew
2007-02-07 14:52 10% Ada.Containers.Doubly_Linked_Lists Carroll, Andrew
2007-02-07 15:06 10% ` Ada.Containers.Doubly_Linked_Lists Ludovic Brenta
2007-02-07 18:22 10%   ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
2007-02-08 13:39 10%     ` Ada.Containers.Doubly_Linked_Lists Stephen Leake
2007-02-07 18:19 10% ` Ada.Containers.Doubly_Linked_Lists Jeffrey R. Carter
2007-02-08 10:44 10%   ` Ada.Containers.Doubly_Linked_Lists Alex R. Mosteo
     [not found]     <mailman.75.1170828524.18371.comp.lang.ada@ada-france.org>
2007-02-07  7:16 10% ` Ada.Containers.Doubly_Linked_Lists Niklas Holsti
2007-02-08 13:37 10% ` Ada.Containers.Doubly_Linked_Lists Stephen Leake
2007-04-11 11:34     Impossible problem? A protected buffer to queue objects of a class-wide type Phil Slater
2007-04-13 17:02  8% ` Matthew Heaney
2007-07-28 17:00  6% Workqueues in Ada Wiktor Moskwa
2007-07-28 17:28  8% ` Dmitry A. Kazakov
2007-07-28 17:52  0%   ` Wiktor Moskwa
2007-07-28 20:45         ` Dmitry A. Kazakov
2007-07-28 21:19           ` Wiktor Moskwa
2007-07-29  8:36             ` Dmitry A. Kazakov
2007-07-29 19:53               ` Wiktor Moskwa
2007-07-30  6:47  8%             ` Niklas Holsti
2007-07-30 15:56  0%               ` Matthew Heaney
2007-07-28 17:31  0% ` Jeffrey R. Carter
2007-07-28 21:54  0% ` Robert A Duff
2007-07-30 15:48  0% ` Matthew Heaney
2008-02-11 14:31  9% Newbie's question Christos Chryssochoidis
2008-02-11 16:28  0% ` Newbie's question [SOLVED] Christos Chryssochoidis
2008-02-22 23:23  9% Learning tagged types mhamel_98
2008-02-23  0:04  0% ` Adam Beneschan
2008-06-17  8:07     Question on initialization of packages Reinert Korsnes
2008-06-17 16:39  5% ` Jeffrey R. Carter
2009-10-29 17:11     Types, packages & objects : the good old naming conventions question (without religious ware) Hibou57 (Yannick Duchêne)
2009-10-29 18:11     ` Georg Bauhaus
2009-10-30 10:52       ` Stephen Leake
2009-10-30 13:40         ` Georg Bauhaus
2009-10-31 11:58  7%       ` Stephen Leake
2010-08-01 12:17     S-expression I/O in Ada Natacha Kerensikova
2010-08-01 18:25  8% ` Jeffrey Carter
2010-08-12 23:26     ` Shark8
2010-08-13  8:56       ` Natacha Kerensikova
2010-08-13 10:30  9%     ` Georg Bauhaus
2010-08-17 17:01     ` Natasha Kerensikova
2010-08-17 19:00       ` Jeffrey Carter
2010-08-18 10:49         ` Natasha Kerensikova
2010-08-24 11:41           ` Natasha Kerensikova
2010-08-25  1:56  5%         ` Jeffrey Carter
2010-08-25 12:18  0%           ` Natasha Kerensikova
2010-08-10 21:38     ANN: Ada 2005 Math Extensions, 20100810 release Simon Wright
2010-08-11 21:38     ` Simon Wright
2010-08-12  5:57       ` Dmitry A. Kazakov
2010-08-12 19:45         ` Simon Wright
2010-08-13  6:27           ` Dmitry A. Kazakov
2010-08-13 13:31             ` Yannick Duchêne (Hibou57)
2010-08-13 13:48  8%           ` Dmitry A. Kazakov
2011-04-20 10:39     If not Ada, what else Alex R. Mosteo
2015-07-10 15:01     ` David Botton
2015-07-10 18:22       ` Paul Rubin
2015-07-10 19:10         ` David Botton
2015-07-10 19:43           ` Patrick Noffke
2015-07-11 10:46             ` Brian Drummond
2015-07-13 14:02               ` Patrick Noffke
2015-07-13 14:16                 ` David Botton
2015-07-16 20:19                   ` Serge Robyns
2015-07-17  1:50                     ` David Botton
2015-07-21  6:30                       ` Gour
2015-07-21 16:24                         ` David Botton
2015-07-21 17:29                           ` Niklas Holsti
2015-07-21 18:51                             ` Simon Wright
2015-07-21 19:36                               ` David Botton
2015-07-22 12:00                                 ` Jean François Martinez
2015-07-27 22:59                                   ` Randy Brukardt
2015-07-29 12:38                                     ` EGarrulo
2015-07-29 15:41                                       ` Paul Rubin
2015-07-29 17:01                                         ` Björn Lundin
2015-07-29 18:27                                           ` Paul Rubin
2015-07-29 18:52  8%                                         ` Björn Lundin
2011-09-17 16:30     discriminant questions ytomino
2011-09-17 17:46     ` ytomino
2011-09-17 19:41       ` Dmitry A. Kazakov
2011-09-17 22:55         ` ytomino
2011-09-18  8:50           ` Dmitry A. Kazakov
2011-09-18 10:54             ` ytomino
2011-09-18 11:35               ` Dmitry A. Kazakov
2011-09-18 16:46                 ` Robert A Duff
2011-09-18 18:01                   ` Dmitry A. Kazakov
2011-09-18 19:20                     ` Maciej Sobczak
2011-09-19  7:39                       ` Dmitry A. Kazakov
2011-09-19 20:00                         ` Maciej Sobczak
2011-09-20  7:33                           ` Dmitry A. Kazakov
2011-09-20 15:45                             ` Maciej Sobczak
2011-09-20 16:48                               ` Dmitry A. Kazakov
2011-09-20 20:19                                 ` Maciej Sobczak
2011-09-21  7:48  8%                               ` Dmitry A. Kazakov
2011-11-12 16:11     Booch Components question Simon Wright
2011-11-14 23:18     ` Randy Brukardt
2011-11-15 10:06       ` Simon Wright
2011-11-15 11:19         ` Simon Wright
2011-11-15 23:26  9%       ` Jeffrey Carter
2011-12-15  0:06     Pop function Rego, P.
2011-12-15  0:34     ` Jeffrey Carter
2011-12-15  8:38       ` Dmitry A. Kazakov
2011-12-15 19:57         ` Jeffrey Carter
2011-12-15 20:15           ` Dmitry A. Kazakov
2011-12-15 21:02             ` Simon Wright
2011-12-15 21:25  8%           ` Jeffrey Carter
2012-06-27  6:43 10% GNAT GPL 2012 bug of iterator? kylix
2012-06-27  7:46  0% ` Martin
2012-08-03 13:30     Should Inline be private in the private part of a package spec? Georg Bauhaus
2012-08-20 19:28     ` Dmitry A. Kazakov
2012-08-21 11:49       ` Georg Bauhaus
2012-08-21 13:12         ` Dmitry A. Kazakov
2012-08-21 14:17           ` Georg Bauhaus
2012-08-21 15:06             ` Dmitry A. Kazakov
2012-08-21 16:18               ` Georg Bauhaus
2012-08-21 19:18                 ` Dmitry A. Kazakov
2012-08-21 21:35                   ` Pascal Obry
2012-08-22  7:32                     ` Dmitry A. Kazakov
2012-08-22 13:12                       ` Georg Bauhaus
2012-08-22 14:30                         ` Dmitry A. Kazakov
2012-08-22 16:48                           ` Georg Bauhaus
2012-08-22 17:44                             ` Dmitry A. Kazakov
2012-08-22 21:18                               ` Georg Bauhaus
2012-08-23  7:23                                 ` Dmitry A. Kazakov
2012-08-23  8:56                                   ` Georg Bauhaus
2012-08-23 10:13                                     ` Dmitry A. Kazakov
2012-08-23 11:33                                       ` Georg Bauhaus
2012-08-23 12:45  7%                                     ` Dmitry A. Kazakov
2014-05-17 22:56     A question about syntax or semantics Victor Porton
2014-05-18  2:47 10% ` Brad Moore
2014-05-18 10:48  0%   ` Simon Wright
2014-05-18  7:32  4% Termination of tasks waiting on a protected queue Natasha Kerensikova
2014-05-18  9:24  0% ` anon
2014-07-28 13:26     Problem with generic linked list package Laurent
2014-07-29  8:27     ` Stephen Leake
2014-07-29 15:38       ` Laurent
2014-08-07 19:07         ` Laurent
2014-08-07 19:21           ` Adam Beneschan
2014-08-07 19:25             ` Adam Beneschan
2014-08-07 22:20               ` Laurent
2014-08-07 23:35                 ` Adam Beneschan
2014-08-08  4:42                   ` Laurent
2014-08-09 14:32                     ` Laurent
2014-08-09 18:51                       ` Shark8
2014-08-09 21:53                         ` Laurent
2014-08-10  8:22                           ` Simon Wright
2014-08-10 10:45                             ` Simon Wright
2014-08-10 20:20                               ` Laurent
2014-08-10 21:57                                 ` Simon Wright
2014-08-10 23:42                                   ` Jeffrey Carter
2014-08-11  4:51                                     ` Laurent
2014-08-11  5:13 10%                                   ` Jeffrey Carter
2014-08-18 18:51 18% how to delete from Ada.Containers.Doubly_Linked_Lists Björn Lundin
2014-08-18 19:57  9% ` Jeffrey Carter
2014-08-19  8:56 10%   ` Björn Lundin
2014-08-19 22:26 10% Curiosity in generic package instantiation GianLuigi Piacentini
2014-08-19 23:16  7% ` Adam Beneschan
2014-08-21 22:39  0%   ` Randy Brukardt
2014-08-20  7:18  0% ` Björn Lundin
2014-10-28  2:01     Queue implementation in Ada compguy45
2014-10-28  3:30  8% ` Jeffrey Carter
2014-10-28 10:00  0%   ` Simon Wright
2014-10-28 18:29  0%     ` Jeffrey Carter
2014-10-28 19:25  0%       ` Simon Wright
2014-11-20 21:08  5% Select then abort can fail to abort the abortable part Jean François Martinez
2014-11-20 21:35  8% ` Dmitry A. Kazakov
2014-11-20 22:19  0%   ` Jean François Martinez
2014-11-21  8:37  0%     ` Dmitry A. Kazakov
2014-11-21 15:26  8%       ` Jean François Martinez
2015-01-04  0:58     How to use read-only variables? hreba
2015-01-04 12:56  7% ` hreba
2015-01-22 21:46     Strange error Laurent
2015-01-23  7:45     ` Egil H H
2015-01-23  8:44       ` Laurent
2015-01-24  0:47  8%     ` Bob Duff
2015-04-17 13:42     Interesting containers problem Shark8
2015-04-17 19:12     ` Peter Chapin
2015-04-17 20:45       ` Randy Brukardt
2015-04-18 17:21         ` Shark8
2015-04-20 23:39  8%       ` Randy Brukardt
2015-07-31 21:13     container of a container Hedley Rainnie
2015-07-31 21:48 11% ` Niklas Holsti
2015-08-01 11:56 11% ` Björn Lundin
2015-08-04 23:56 10% Mutating elements of constant list using a container element iterator martinbbjerregaard
2015-12-29 11:50  5% Generalized Iterators AdaMagica
2016-04-05  2:03  7% Ada 2005,Doubly_Linked_List with Controlled parameter George J
2017-07-01  7:11  6% cobegin ... coend G.B.
2017-09-11 21:19  9% Convert between different container types Victor Porton
2017-09-11 21:20  0% ` Victor Porton
2017-10-02 23:29  0%   ` Randy Brukardt
2017-09-11 21:36  0% ` Simon Wright
2018-01-25  0:22     Iterable container as generic parameter Lionel Draghi
2018-01-25  3:36     ` Randy Brukardt
2018-01-25 14:58 11%   ` Lionel Draghi
2018-02-09  0:46     grassroots thoughts on access types Mehdi Saada
2018-02-09 17:01     ` Jeffrey R. Carter
2018-02-09 17:19       ` Dmitry A. Kazakov
2018-02-09 19:12         ` Jeffrey R. Carter
2018-02-09 20:17           ` Robert A Duff
2018-02-09 21:44             ` Jeffrey R. Carter
2018-02-09 22:06               ` Dmitry A. Kazakov
2018-02-10  0:43                 ` Mehdi Saada
2018-02-10  1:51                   ` Mehdi Saada
2018-02-10 11:57                     ` Mehdi Saada
2018-02-10 15:32  8%                   ` Jeffrey R. Carter
2020-04-12 12:32 10% 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  7% ` Jeffrey R. Carter
2020-04-14 12:09  0%   ` ldries46
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         ` Stephen Leake
2020-12-06 21:09  8%       ` Björn Lundin
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 20:32                     ` Jeffrey R. Carter
2021-04-20 21:10                       ` Niklas Holsti
2021-04-24  0:49                         ` Randy Brukardt
2022-04-18  1:51  8%                       ` Thomas

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