comp.lang.ada
 help / color / mirror / Atom feed
From: Christos Chryssochoidis <C.Chryssochoidis@gmail.com>
Subject: Re: Newbie's question
Date: Wed, 13 Feb 2008 00:56:15 +0200
Date: 2008-02-13T00:56:15+02:00	[thread overview]
Message-ID: <1202856976.51300@athprx04> (raw)
In-Reply-To: <rO%rj.29068$yE1.16792@attbi_s21>



Jeffrey R. Carter wrote:
> 
> Christos Chryssochoidis wrote:
> 
> Apparently you found a compiler error. Some comments on your code:
> 
>>       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));
> 
> This is OK for a little test program like this, but in real code, you 
> have a memory leak from this use of access values and heap allocation 
> that you should want to avoid. You can do that by moving the declaration 
> of Result into Copy_List below:
> 
> Result : Int_Array (1 .. Index (Tmp_List.Length) );

I ruled out the declaration of a local array within the block statement 
Copy_List, because I thought that the compiler would mandate a return 
statement to be at the top level of the function's body, which I 
wouldn't be able to do, since the declared array would be local to the 
block statement. Surprisingly I realized I was wrong; this solution 
compiles fine. The compiler doesn't complain about not finding a return 
statement at the outermost scope of the function.



> 
> You might also find an unbounded array (Ada.Containers.Vectors) more 
> suited than a list here, since you can use the same index for both.

Good point.

> 
>>   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;
> 
> Rather than using a cursor and a loop, I would probably use the Iterate 
> procedure to convert the list into an array.

I tried it. (Code below.) It works fine. Thanks.


Copy_List:
       declare
          Result : Int_Array(0..Index(Tmp_Vector.Length)-1);
          I : Integer := 0;
          procedure Copy(Position: Int_Vectors.Cursor) is
          begin
             Result(I) := Int_Vectors.Element(Position);
             I := I + 1;
          end Copy;

       begin
          Tmp_Vector.Iterate(Copy'Access);

          return Result;
       end Copy_List;





> 
> You could also make Filter recursive and eliminate Result and Tmp_List 
> altogether:
> 
> begin -- Filter
>    if Elements'Length <= 0 then
>       return Elements;
>    elsif Predicate (Elements (Elements'First) ) then
>       return Elements'First &
>              Filter (Elements (Elements'First + 1 .. Elements'Last), 
> Predicate);
>    else
>       return Filter (Elements (Elements'First + 1 .. Elements'Last), 
> Predicate);
>    end if;
> end Filter;

I thought too about doing it recursively, but stubbornly I wanted to 
find a way to do that iteratively, as that's how I would do it in other 
languages I 'm familiar with…

> 
>>    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;
> 
> This should be
> 
> return Element >= 3;

That's much simpler, I agree.

> 
> Personally, I'd make filter generic rather than passing the Predicate 
> function as a subprogram parameter.
> 

I made another version of my code using a generic subprogram as you 
suggested. That's also an elegant solution.

Thanks very much for all your suggestions.



  reply	other threads:[~2008-02-12 22:56 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-11 14:31 Newbie's question Christos Chryssochoidis
2008-02-11 16:28 ` Newbie's question [SOLVED] Christos Chryssochoidis
2008-02-11 17:42 ` Newbie's question Jeffrey R. Carter
2008-02-12 22:56   ` Christos Chryssochoidis [this message]
2008-02-13 11:06     ` Christos Chryssochoidis
replies disabled

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