> The nesting issue really involves nested variable declarations. > Sometimes variables do need to be nested: > > with Ada.Text_IO;... > function Get_Matrix return Matrix is > Number_of_Rows, Number_of_Columns: Integer; > ... > begin > Get(Number_of_Rows); > Get(Number_of_Columns); > declare > Result: Matrix(Number_of_Rows, Number_of_Columns) := (others => 0); > begin > for I in 1..Number_of_Rows loop > for J in 1..Number_of_Columns loop > Get(Result(I,J)); > end loop; > end loop; > end; > end Get_Matrix; > > But, and this is the key, such nesting almost always involves delcare > blocks, not subprograms, or not just subprograms. On the other hand, Get could be a function.... function Get (Prompt : String := "") return Integer is .... with Ada.Text_IO;... function Get_Matrix return Matrix is Result: Matrix (1 .. Get ("Rows: "), 1 .. Get ("Columns: ")); begin for I in Matrix'Range(1) loop for J in Matrix'Range(2) loop Result(I,J) := Get ("Value(" & Integer'Image (I) & "," Integer'Image (J) & "): " ); end loop; end loop; return Result; -- don't forget this... end Get_Matrix; And some of that input could easily be "lifted" to function Get_Matrix ( Rows, Columns : Integer ) return .... I find declare blocks valuable aids to localization, information hiding, and sometimes for readability. However, if they are unnecessary, they can act as "clutter," obscuring more important stuff.