comp.lang.ada
 help / color / mirror / Atom feed
* About String
@ 2008-06-06 17:29 Sébastien Morand
  2008-06-07 16:18 ` Simon Wright
  0 siblings, 1 reply; 38+ messages in thread
From: Sébastien Morand @ 2008-06-06 17:29 UTC (permalink / raw)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I'm curious about how you are using string. I think string are quite
useful, but how they are fixed size, I'm often defining them in the
declare part.

I don't know if it's a good practice, but I got code like this:

      urio: constant AWS.URL.Object := AWS.Status.URI(request);
      host_raw: constant String := AWS.Status.Host(request);
      host: constant String := host_raw(host_raw'First ..
First_Index(host_raw, ':'));
      www: constant String := SCMAL.Httpd.Servers.GetWWW(host);
      Filename: constant String := AWS.URL.Abs_Path(urio);

and so on.

So the main problem is error management. If one function raise
exception, the exception can't be catch except with the following trick:

procedure Patati_Patata is
begin
	declare
		s: String := A_Function_Raising_Constraint_Error;
	begin
		--  some code
		null;
	end;
exception
	when Constraint_Error =>
		Put_Line("I got an error");
end;

Is there nicer way to do that? I'm trying to avoid Unbounded_String
because of the conversion when mixing Unbounded_String and String.

S�bastien
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)

iD8DBQFISXQH+zV9xm4PlDQRAp1AAJ98x/YTeiFzGP4PGJeL+7B2+iLtRQCggbzh
Xcv5gRRjhmFVnCqVVQRk4QM=
=tG7M
-----END PGP SIGNATURE-----



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-06 17:29 About String Sébastien Morand
@ 2008-06-07 16:18 ` Simon Wright
  2008-06-07 17:01   ` Pascal Obry
  0 siblings, 1 reply; 38+ messages in thread
From: Simon Wright @ 2008-06-07 16:18 UTC (permalink / raw)


S�bastien Morand <seb.morand@gmail.com> writes:

> So the main problem is error management. If one function raise
> exception, the exception can't be catch except with the following trick:

I don't know why you call it a trick! Perfectly standard Ada ...

> procedure Patati_Patata is
> begin
> 	declare
> 		s: String := A_Function_Raising_Constraint_Error;
> 	begin
> 		--  some code
> 		null;
> 	end;
> exception
> 	when Constraint_Error =>
> 		Put_Line("I got an error");
> end;
>
> Is there nicer way to do that? I'm trying to avoid Unbounded_String
> because of the conversion when mixing Unbounded_String and String.

You might want to handle the problem locally:

   procedure Patati_Patata is
   begin
      declare
         S : String := A_Function_Raising_Constraint_Error;
      begin
         --  some code
      exception
         when Constraint_Error =>
            --  deal with the problem and carry on ..
      end;
      --  .. here
   end Patati_Patata;

In general I don't like exception handlers which output a message and
then allow the procedure to look as though it has succeeded when in
fact something unforeseen has occurred, and is waiting to cause
mysterious problems much much later. Exceptions to this guideline
could include 'last-chance' exception handlers in tasks and the main
program; but if you are controlling missiles, medical equipment or
money it's probably better not to just stumble on in the hope that
things will turn out all right.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-07 16:18 ` Simon Wright
@ 2008-06-07 17:01   ` Pascal Obry
  2008-06-07 22:13     ` Chris Moore
  2008-06-08 11:13     ` Simon Wright
  0 siblings, 2 replies; 38+ messages in thread
From: Pascal Obry @ 2008-06-07 17:01 UTC (permalink / raw)
  To: Simon Wright

Simon Wright a �crit :
> You might want to handle the problem locally:
> 
>    procedure Patati_Patata is
>    begin
>       declare
>          S : String := A_Function_Raising_Constraint_Error;
>       begin
>          --  some code
>       exception
>          when Constraint_Error =>
>             --  deal with the problem and carry on ..
>       end;
>       --  .. here

This one is wrong. The exception on the declare section can't be handled 
on the local block as it will raised outside of the block.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-07 17:01   ` Pascal Obry
@ 2008-06-07 22:13     ` Chris Moore
  2008-06-08  6:47       ` Niklas Holsti
  2008-06-08 11:13     ` Simon Wright
  1 sibling, 1 reply; 38+ messages in thread
From: Chris Moore @ 2008-06-07 22:13 UTC (permalink / raw)


Pascal Obry wrote:
> Simon Wright a �crit :
>> You might want to handle the problem locally:
>>
>>    procedure Patati_Patata is
>>    begin
>>       declare
>>          S : String := A_Function_Raising_Constraint_Error;
>>       begin
>>          --  some code
>>       exception
>>          when Constraint_Error =>
>>             --  deal with the problem and carry on ..
>>       end;
>>       --  .. here
> 
> This one is wrong. The exception on the declare section can't be handled 
> on the local block as it will raised outside of the block.
> 
> Pascal.
> 

You are correct.  I have to say this is an entirely non-intuitive 
"feature" of the language.  We talk about declare blocks and yet the 
scope of the exception handlers doesn't include the declarations!   And 
the OP is correct in noticing that without the inner declare block 
exceptions raised in the outermost declarative section leak into the 
calling subprogram.  Ugh.

Chris



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-07 22:13     ` Chris Moore
@ 2008-06-08  6:47       ` Niklas Holsti
  2008-06-08  7:35         ` Dmitry A. Kazakov
  2008-06-08 18:32         ` Robert A Duff
  0 siblings, 2 replies; 38+ messages in thread
From: Niklas Holsti @ 2008-06-08  6:47 UTC (permalink / raw)


Chris Moore wrote:
> Pascal Obry wrote:
> 
>> Simon Wright a �crit :
>>
>>> You might want to handle the problem locally:
>>>
>>>    procedure Patati_Patata is
>>>    begin
>>>       declare
>>>          S : String := A_Function_Raising_Constraint_Error;
>>>       begin
>>>          --  some code
>>>       exception
>>>          when Constraint_Error =>
>>>             --  deal with the problem and carry on ..
>>>       end;
>>>       --  .. here
>>
>>
>> This one is wrong. The exception on the declare section can't be 
>> handled on the local block as it will raised outside of the block.
>>
>> Pascal.
>>
> 
> You are correct.

Yes.

> I have to say this is an entirely non-intuitive "feature" of the language.

I beg to differ. The program should be read as

     declare <some variables>
     begin <do something with those variables> end;

The exception handler is within the "begin..end" block, not on the 
"declare". (Indenting the "begin..exception..end" structure one 
level beyond the "declare" would make this more visible, but is not 
common practice.)

> We talk about declare blocks and yet the 
> scope of the exception handlers doesn't include the declarations!

The declared variables are visible in the whole "begin..end" block, 
including in the exception handler. If the declarations raise an 
exception, it would be madness to try to handle it within the 
"begin..end" block, because the handler could try to use 
un-elaborated (non-existent) variables.

The solution is just to add one more "begin..end" block, enclosing 
the "declare .. begin .. end", and handle the exceptions in this 
outer "begin..end" block. Or handle the exceptions in the 
subprogram's "begin..end" block and nest the "declare..begin..end" 
within the subprograms "begin..end".

That said, I admit that I, too, have made this mistake once or 
twice. But not lately.

I wonder if it would be a good idea for Ada to allow an exception 
handler also in the "declare" part, as follows:

    -- NOT Ada!
    declare <some variables>
    exception <handle exceptions raised in the declarations>
    begin <some statements>
    exception <handle exceptions raised in the statements>
    end;

Of course, in this proposal the declaration-exception handler would 
not have access to the declared variables.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08  6:47       ` Niklas Holsti
@ 2008-06-08  7:35         ` Dmitry A. Kazakov
  2008-06-08 10:29           ` Sebastien Morand
                             ` (3 more replies)
  2008-06-08 18:32         ` Robert A Duff
  1 sibling, 4 replies; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-08  7:35 UTC (permalink / raw)


On Sun, 08 Jun 2008 09:47:30 +0300, Niklas Holsti wrote:

> The solution is just to add one more "begin..end" block, enclosing 
> the "declare .. begin .. end", and handle the exceptions in this 
> outer "begin..end" block. Or handle the exceptions in the 
> subprogram's "begin..end" block and nest the "declare..begin..end" 
> within the subprograms "begin..end".
> 
> That said, I admit that I, too, have made this mistake once or 
> twice. But not lately.

If exceptions were contracted such, quite nasty, errors could be detected
at compile time.

> I wonder if it would be a good idea for Ada to allow an exception 
> handler also in the "declare" part, as follows:
> 
>     -- NOT Ada!
>     declare <some variables>
>     exception <handle exceptions raised in the declarations>
>     begin <some statements>
>     exception <handle exceptions raised in the statements>
>     end;
> 
> Of course, in this proposal the declaration-exception handler would 
> not have access to the declared variables.

But then, for regularity sake, you would need to add exception handling to
all declarative parts:

package A is
    <some declarations>
exception
    <handling elaboration problems of A, HOW?>  (:-))
end A;

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08  7:35         ` Dmitry A. Kazakov
@ 2008-06-08 10:29           ` Sebastien Morand
  2008-06-08 10:53             ` Dmitry A. Kazakov
  2008-06-08 11:14           ` Niklas Holsti
                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 38+ messages in thread
From: Sebastien Morand @ 2008-06-08 10:29 UTC (permalink / raw)


Thanks for all you answer. I m happy to see I did the right way.

Actually not handling exception of the declaring part can be non intuitive at 
first. But I think it is. If you could, you wouldn't know wich data is available 
since you don't know where the exception take place in the declarative part. So 
it's better to handle it externally where you know wich variables are already 
defined. the only matter is that you can handle exception in declarative part of 
a function/procedure. So you have to declare it in subblock and then handle the 
exception. The problem is, if you can't anymore use the string in the body of 
the function, only in the subblock.

Sebastien



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08 10:29           ` Sebastien Morand
@ 2008-06-08 10:53             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-08 10:53 UTC (permalink / raw)


On Sun, 08 Jun 2008 10:29:53 +0000, Sebastien Morand wrote:

> The problem is, if you can't anymore use the string in the body of 
> the function, only in the subblock.

Which is absolutely consistent.

Consider it as follows. When the initialization of an object used in the
subprogram body may fail, that means for the body, that there are two
different cases:

1. Object exists, legally initialized of course [case A]
2. No object exists (because it cannot go through initialization) [case B]

This means that the body shall necessarily consist of two parts. Note that
the precondition of B is weaker than one of A. So B can contain A, but not
reverse. Therefore there exist only two variants:

1. A nested in B (this what Ada provides)
2. A side by side with B. This would require some syntax extensions, like
Niklas has outlined, but without obvious advantages.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-07 17:01   ` Pascal Obry
  2008-06-07 22:13     ` Chris Moore
@ 2008-06-08 11:13     ` Simon Wright
  2008-06-08 19:03       ` Sebastien Morand
  1 sibling, 1 reply; 38+ messages in thread
From: Simon Wright @ 2008-06-08 11:13 UTC (permalink / raw)


Pascal Obry <pascal@obry.net> writes:

> Simon Wright a �crit :
>> You might want to handle the problem locally:
>>
>>    procedure Patati_Patata is
>>    begin
>>       declare
>>          S : String := A_Function_Raising_Constraint_Error;
>>       begin
>>          --  some code
>>       exception
>>          when Constraint_Error =>
>>             --  deal with the problem and carry on ..
>>       end;
>>       --  .. here
>
> This one is wrong. The exception on the declare section can't be
> handled on the local block as it will raised outside of the block.

:blush:

I meant to say

   procedure Patati_Patata is
   begin
      begin
         declare
            S : String := A_Function_Raising_Constraint_Error;
         begin
            --  some code
         end;
      exception
         when Constraint_Error =>
            --  deal with the problem ..
      end;
      --  .. and carry on
   end;



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08  7:35         ` Dmitry A. Kazakov
  2008-06-08 10:29           ` Sebastien Morand
@ 2008-06-08 11:14           ` Niklas Holsti
  2008-06-08 13:16             ` Dmitry A. Kazakov
  2008-06-08 11:48           ` Martin
  2008-06-08 18:26           ` About String Chris Moore
  3 siblings, 1 reply; 38+ messages in thread
From: Niklas Holsti @ 2008-06-08 11:14 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On Sun, 08 Jun 2008 09:47:30 +0300, Niklas Holsti wrote:
> 
> 
>>The solution is just to add one more "begin..end" block, enclosing 
>>the "declare .. begin .. end", and handle the exceptions in this 
>>outer "begin..end" block. Or handle the exceptions in the 
>>subprogram's "begin..end" block and nest the "declare..begin..end" 
>>within the subprograms "begin..end".
>>
>>That said, I admit that I, too, have made this mistake once or 
>>twice. But not lately.
> 
> 
> If exceptions were contracted such, quite nasty, errors could be detected
> at compile time.

Only if the programmer specifies the exception contracts separately 
for the declarative parts and the statements. I don't remember any 
such proposals.

>>I wonder if it would be a good idea for Ada to allow an exception 
>>handler also in the "declare" part, as follows:
>>
>>    -- NOT Ada!
>>    declare <some variables>
>>    exception <handle exceptions raised in the declarations>
>>    begin <some statements>
>>    exception <handle exceptions raised in the statements>
>>    end;
>>
>>Of course, in this proposal the declaration-exception handler would 
>>not have access to the declared variables.
> 
> 
> But then, for regularity sake, you would need to add exception handling to
> all declarative parts:

And why not?

> package A is
>     <some declarations>
> exception
>     <handling elaboration problems of A, HOW?>  (:-))
> end A;

It seems, from your smiley, that you feel that such a structure 
would be somehow impossible. I don't see why; the exception handler 
could execute any sort of non-erroneous code that could be executed 
in any subprogram called as part of the declarations in package A. 
For example, it could set some flag in another package to inform 
the application that package A cannot be used because its 
elaboration failed. If the application uses run-time elaboration 
checks, it could even continue executing, as long as it does not 
try to use anything in A. I admit that this might need an extended 
form of run-time elaboration checks.

I'm not suggesting that this feature (exception handlers in package 
declarations) is desirable, but I don't think it would be 
impossible, and it could even be useful in some applications.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08  7:35         ` Dmitry A. Kazakov
  2008-06-08 10:29           ` Sebastien Morand
  2008-06-08 11:14           ` Niklas Holsti
@ 2008-06-08 11:48           ` Martin
  2008-06-08 13:17             ` Conditional declarations (was: About String) Dmitry A. Kazakov
  2008-06-08 18:26           ` About String Chris Moore
  3 siblings, 1 reply; 38+ messages in thread
From: Martin @ 2008-06-08 11:48 UTC (permalink / raw)


On 8 Jun, 08:35, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Sun, 08 Jun 2008 09:47:30 +0300, Niklas Holsti wrote:
> > The solution is just to add one more "begin..end" block, enclosing
> > the "declare .. begin .. end", and handle the exceptions in this
> > outer "begin..end" block. Or handle the exceptions in the
> > subprogram's "begin..end" block and nest the "declare..begin..end"
> > within the subprograms "begin..end".
>
> > That said, I admit that I, too, have made this mistake once or
> > twice. But not lately.
>
> If exceptions were contracted such, quite nasty, errors could be detected
> at compile time.
>
> > I wonder if it would be a good idea for Ada to allow an exception
> > handler also in the "declare" part, as follows:
>
> >     -- NOT Ada!
> >     declare <some variables>
> >     exception <handle exceptions raised in the declarations>
> >     begin <some statements>
> >     exception <handle exceptions raised in the statements>
> >     end;
>
> > Of course, in this proposal the declaration-exception handler would
> > not have access to the declared variables.
>
> But then, for regularity sake, you would need to add exception handling to
> all declarative parts:
>
> package A is
>     <some declarations>
> exception
>     <handling elaboration problems of A, HOW?>  (:-))
> end A;

Admittedly the range of options is pretty limited if exception
handlers where to be added to package specs but you could log an
indication in a package local variable, set a default or re-raise the
exception.

I rather like the idea...that forced nesting just to catch an
exception is quite ugly and dare I day, goes against Ada's "easy to
read and therefore maintain" mantra...

Cheers
-- Martin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08 11:14           ` Niklas Holsti
@ 2008-06-08 13:16             ` Dmitry A. Kazakov
  2008-06-08 17:17               ` Niklas Holsti
  0 siblings, 1 reply; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-08 13:16 UTC (permalink / raw)


On Sun, 08 Jun 2008 14:14:04 +0300, Niklas Holsti wrote:

> Dmitry A. Kazakov wrote:
>> On Sun, 08 Jun 2008 09:47:30 +0300, Niklas Holsti wrote:
>> 
>>>The solution is just to add one more "begin..end" block, enclosing 
>>>the "declare .. begin .. end", and handle the exceptions in this 
>>>outer "begin..end" block. Or handle the exceptions in the 
>>>subprogram's "begin..end" block and nest the "declare..begin..end" 
>>>within the subprograms "begin..end".
>>>
>>>That said, I admit that I, too, have made this mistake once or 
>>>twice. But not lately.
>> 
>> If exceptions were contracted such, quite nasty, errors could be detected
>> at compile time.
> 
> Only if the programmer specifies the exception contracts separately 
> for the declarative parts and the statements. I don't remember any 
> such proposals.

I had this in mind:

function Boo raise Use_Error return String; -- That's not Ada
procedure Foo raise null;

procedure Foo is 
   X : String := Boo;
begin
   ...
exception
   when Use_Error => -- The handler is misplaced
      ...
end Foo;

This won't compile because Use_Error is not handled when propagates out of
Boo. But the contract of Foo promises no Use_Error.

>>>I wonder if it would be a good idea for Ada to allow an exception 
>>>handler also in the "declare" part, as follows:
>>>
>>>    -- NOT Ada!
>>>    declare <some variables>
>>>    exception <handle exceptions raised in the declarations>
>>>    begin <some statements>
>>>    exception <handle exceptions raised in the statements>
>>>    end;
>>>
>>>Of course, in this proposal the declaration-exception handler would 
>>>not have access to the declared variables.
>> 
>> But then, for regularity sake, you would need to add exception handling to
>> all declarative parts:
> 
> And why not?

Because that would make the margin between declarative and imperative more
fuzzy than it already is.

>> package A is
>>     <some declarations>
>> exception
>>     <handling elaboration problems of A, HOW?>  (:-))
>> end A;
> 
> It seems, from your smiley, that you feel that such a structure 
> would be somehow impossible. I don't see why; the exception handler 
> could execute any sort of non-erroneous code that could be executed 
> in any subprogram called as part of the declarations in package A. 
> For example, it could set some flag in another package to inform 
> the application that package A cannot be used because its 
> elaboration failed. If the application uses run-time elaboration 
> checks, it could even continue executing, as long as it does not 
> try to use anything in A. I admit that this might need an extended 
> form of run-time elaboration checks.

There are two models of exception handling:

1. Handle and continue
2. Wind-up then handle

The first was used by PL/1, I cannot tell if it still has it. The second is
Ada's model. It is sufficiently simpler (no upward closures etc) and also
more general, because it allows continuation without fixing.

Fixing a failed declaration would be the first model. I don't see how this
could be made, because the exception handler cannot see failed stuff. Which
is because it is still the second model... They don't live together.

For the second model, it is unclear what will be the status of failed A?
Say, B with-es A and A has failed. That means that B should also fail. But:

with A;
package B is
   ...
exception
   -- I still cannot handle A's failure here!
end B;

So we would need something like exception handlers in with!

with A
   package B
      ...
   end B;
exception
   -- OK, I can handle A's failure, but what happened with B?
end with A;

Nevertheless we still cannot do anything in order to fix B.

It seems that declarations could not be fixed in the second model.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Conditional declarations (was: About String)
  2008-06-08 11:48           ` Martin
@ 2008-06-08 13:17             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-08 13:17 UTC (permalink / raw)


On Sun, 8 Jun 2008 04:48:56 -0700 (PDT), Martin wrote:

> On 8 Jun, 08:35, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:

>> package A is
>> � � <some declarations>
>> exception
>> � � <handling elaboration problems of A, HOW?> �(:-))
>> end A;
> 
> Admittedly the range of options is pretty limited if exception
> handlers where to be added to package specs but you could log an
> indication in a package local variable, set a default or re-raise the
> exception.

Aha, so many people are looking for Ada preprocessor! (:-)) What about
catching compile error in with-ing OS.Linux in order to with OS.Windows
instead? (:-))

> I rather like the idea...that forced nesting just to catch an
> exception is quite ugly and dare I day, goes against Ada's "easy to
> read and therefore maintain" mantra...

I think it could be solved in a different way, together with a closely
related  problem:

   if X in T'Class then
      declare
         TX : T'Class renames T'Class (X);
      begin
         ...
      end;
   end if;

   if Ptr /= null then
      declare
         Ptr_All : T renames Ptr.all;
      begin
         ...
      end;
   end if;

This is a pretty frequent and quite ugly construct, especially because it
verifies the same condition twice.

I think that a fail-safe declaration is in essence a similar thing. It need
not to appear in the main declaration block, because it a combination of a
flow control and visibility scope.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08 13:16             ` Dmitry A. Kazakov
@ 2008-06-08 17:17               ` Niklas Holsti
  2008-06-09  7:26                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 38+ messages in thread
From: Niklas Holsti @ 2008-06-08 17:17 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On Sun, 08 Jun 2008 14:14:04 +0300, Niklas Holsti wrote:
> 
>>Dmitry A. Kazakov wrote:
>>
>>>On Sun, 08 Jun 2008 09:47:30 +0300, Niklas Holsti wrote:

>>> [ About the fact that exceptions raised in a declarative
 >>>   part cannot be handled by the handler in the following
>>>   handled_sequence_of_statements, and it is an error
 >>>   to try. ]
>>>
>>>If exceptions were contracted such, quite nasty, errors could be detected
>>>at compile time.
>>
>>Only if the programmer specifies the exception contracts separately 
>>for the declarative parts and the statements. I don't remember any 
>>such proposals.
> 
> 
> I had this in mind:
> 
> function Boo raise Use_Error return String; -- That's not Ada
> procedure Foo raise null;
> 
> procedure Foo is 
>    X : String := Boo;
> begin
>    ...
> exception
>    when Use_Error => -- The handler is misplaced
>       ...
> end Foo;
> 
> This won't compile because Use_Error is not handled when propagates out of
> Boo. But the contract of Foo promises no Use_Error.

I agree that exception contracts would work in this example. Ok, 
exception contracts would reveal some -- perhaps most -- of these 
errors at compile time, but not all.

>>>>I wonder if it would be a good idea for Ada to allow an exception 
>>>>handler also in the "declare" part, as follows:
>>>>
>>>>   -- NOT Ada!
>>>>   declare <some variables>
>>>>   exception <handle exceptions raised in the declarations>
>>>>   begin <some statements>
>>>>   exception <handle exceptions raised in the statements>
>>>>   end;
>>>>
>>>>Of course, in this proposal the declaration-exception handler would 
>>>>not have access to the declared variables.
>>>
>>>But then, for regularity sake, you would need to add exception handling to
>>>all declarative parts:
>>
>>And why not?
> 
> 
> Because that would make the margin between declarative and imperative more
> fuzzy than it already is.

That is a philosophical reason, and I might even agree with it, but 
it is not a technical problem.

>>>package A is
>>>    <some declarations>
>>>exception
>>>    <handling elaboration problems of A, HOW?>  (:-))
>>>end A;
>>
>>It seems, from your smiley, that you feel that such a structure 
>>would be somehow impossible. I don't see why; the exception handler 
>>could execute any sort of non-erroneous code that could be executed 
>>in any subprogram called as part of the declarations in package A. 
>>For example, it could set some flag in another package to inform 
>>the application that package A cannot be used because its 
>>elaboration failed. If the application uses run-time elaboration 
>>checks, it could even continue executing, as long as it does not 
>>try to use anything in A. I admit that this might need an extended 
>>form of run-time elaboration checks.
> 
> 
> There are two models of exception handling:
> 
> 1. Handle and continue
> 2. Wind-up then handle
> 
> The first was used by PL/1, I cannot tell if it still has it. The second is
> Ada's model. It is sufficiently simpler (no upward closures etc) and also
> more general, because it allows continuation without fixing.

Yes. And I like the Ada approach better.

> Fixing a failed declaration would be the first model. I don't see how this
> could be made, because the exception handler cannot see failed stuff. Which
> is because it is still the second model... They don't live together.

I agree that an exception handler in a package declaration could 
not do anything to recover or repair the failed elaboration (unless 
the package declaration is nested in a subprogram, of course, so 
that the subprogram may be called again with better success).

But such an exception handler could still do something useful, for 
example by logging the problem, invoking some "safing" actions, 
etc., as long as these actions do not depend on the package that 
failed its elaboration.

> For the second model, it is unclear what will be the status of failed A?

The Ada run-time semantics already has a concept of something (eg. 
a subprogram) that is not "yet" elaborated, and can potentially be 
invoked before it is elaborated, triggering a run-time elaboration 
check and possible raising of Program_Error. A package with a 
failed elaboration could be in a similar state.

Note again that I'm not proposing that exception handlers should be 
allowed in package declarations, just exploring the theoretical 
possibility.

> Say, B with-es A and A has failed. That means that B should also fail.

Sure, why not. If A's elaboration fails, all subsystems depending 
on A should be unusable. I think some distinction between failing 
package declarations and failing package bodies could be used to 
contain the spreading of the failure.

>    -- I still cannot handle A's failure here!

I agree that an application could not *recover* from failures in 
package elaboration. But the application could possibly fail more 
gracefully, perhaps even continue operating in a degraded mode.

> It seems that declarations could not be fixed in the second model.

Only in the (unusual) case where a package is nested in a callable 
entity. If the package elaboration fails on one call, the exception 
handlers could take some action that makes the next call succeed 
better. In theory.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08  7:35         ` Dmitry A. Kazakov
                             ` (2 preceding siblings ...)
  2008-06-08 11:48           ` Martin
@ 2008-06-08 18:26           ` Chris Moore
  3 siblings, 0 replies; 38+ messages in thread
From: Chris Moore @ 2008-06-08 18:26 UTC (permalink / raw)


> On Sun, 08 Jun 2008 09:47:30 +0300, Niklas Holsti wrote:
> 
>> That said, I admit that I, too, have made this mistake once or 
>> twice. But not lately.

Me too.  I think it's one of those mistakes that sticks in the mind.

Dmitry A. Kazakov wrote:

> But then, for regularity sake, you would need to add exception handling to
> all declarative parts:
> 
> package A is
>     <some declarations>
> exception
>     <handling elaboration problems of A, HOW?>  (:-))
> end A;
> 

It might make tracing elaboration errors easier.  :)

Barnes says "... in any handler we are assured that all declarations of 
the unit were successfully elaborated and so there's no risk of 
referring to something that does not exist."  That's sensible but it 
does mean the compiler has to undo memory allocations if they occur in a 
declaration and a subsequent declaration raises an exception.

Chris



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08  6:47       ` Niklas Holsti
  2008-06-08  7:35         ` Dmitry A. Kazakov
@ 2008-06-08 18:32         ` Robert A Duff
  2008-06-08 20:51           ` Maciej Sobczak
  1 sibling, 1 reply; 38+ messages in thread
From: Robert A Duff @ 2008-06-08 18:32 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> Chris Moore wrote:
>> I have to say this is an entirely non-intuitive "feature" of the language.
>
> I beg to differ. The program should be read as
>
>     declare <some variables>
>     begin <do something with those variables> end;
>
> The exception handler is within the "begin..end" block, not on the
> "declare".

Sure, that's right, but the syntax doesn't make it clear.
We have ample proof that this syntax is confusing:
More than one person in this thread has admitted to
being confused -- QED.  ;-)

I think it was a mistake to attach exception handlers
to declare blocks and procedures and so forth.  Instead,
there should be a single statement for handling exceptions,
as in Java and other languages.  Something like:

    handle
        ... statements ...
    exception
        when ... =>
            ...
    end;

>... (Indenting the "begin..exception..end" structure one level
> beyond the "declare" would make this more visible, but is not common
> practice.)

And it violates the recommended indentation defined by the RM.

Anyway, surely "end" belongs at the same column as "declare"
or "procedure" or whatever it's ending.

> I wonder if it would be a good idea for Ada to allow an exception
> handler also in the "declare" part, as follows:

That goes in the opposite direction I suggested above.
I think it would add confusion.

- Bob



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08 11:13     ` Simon Wright
@ 2008-06-08 19:03       ` Sebastien Morand
  0 siblings, 0 replies; 38+ messages in thread
From: Sebastien Morand @ 2008-06-08 19:03 UTC (permalink / raw)


> I meant to say
> 
>    procedure Patati_Patata is
>    begin
>       begin
>          declare
>             S : String := A_Function_Raising_Constraint_Error;
>          begin
>             --  some code
>          end;
>       exception
>          when Constraint_Error =>
>             --  deal with the problem ..
>       end;
>       --  .. and carry on
>    end;

And it's what exactly I don't think pretty nice and easy to maintain. Other 
solution proposed by previous post is to separate the code with nested function:

procedure Patati_Patata is

    function Manage_S return String;

    function Manage_S return String is
    begin
       declare
          S : String := A_Function_Raising_Constraint_Error;
       begin
          --  some code
          return S;
       end;
    exception
       when Constraint_Error =>
          --  deal with the problem ..
          return ""; --  Or something else to manage the error but something 
must be returned to be consistent
    end;

    S: String := Manage_S;

begin
    --  .. and carry on
end;

I think it's a better way especially because:
1) You can put away the nested function (for instance as a private package function)
2) You can reuse the function
3) You string are constant most of time (meaning: "S: constant String := Manage_S;")

The only disadvantage for me is that you write a lot little function if you use 
a lot of string (and frankly, you always do in high level application).

I wonder too if there is a nice way to manipulate string using access type. I 
don't choose to try this way because I think it's the better way to introduce 
some memory link.

Sebastien



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08 18:32         ` Robert A Duff
@ 2008-06-08 20:51           ` Maciej Sobczak
  2008-06-08 21:19             ` Robert A Duff
  0 siblings, 1 reply; 38+ messages in thread
From: Maciej Sobczak @ 2008-06-08 20:51 UTC (permalink / raw)


On 8 Cze, 20:32, Robert A Duff <bobd...@shell01.TheWorld.com> wrote:

> I think it was a mistake to attach exception handlers
> to declare blocks and procedures and so forth.  Instead,
> there should be a single statement for handling exceptions,
> as in Java and other languages.  Something like:
>
>     handle
>         ... statements ...
>     exception
>         when ... =>
>             ...
>     end;

You did not state it explicitly, but I presume that you allow mixing
declarations with executable code ("as in Java and other languages")?
After all, with the possibility to initialize the new variable with
arbitrarily complex expression (including function call), this is
already the case and the whole declare-begin-end block is just
reflecting some artificial separation.

Get rid of this artificial separation and the problem of exceptions
will be solved.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08 20:51           ` Maciej Sobczak
@ 2008-06-08 21:19             ` Robert A Duff
  2008-06-09  7:14               ` Dmitry A. Kazakov
  2008-06-09 11:00               ` Georg Bauhaus
  0 siblings, 2 replies; 38+ messages in thread
From: Robert A Duff @ 2008-06-08 21:19 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

> You did not state it explicitly, but I presume that you allow mixing
> declarations with executable code ("as in Java and other languages")?

Yes, if I ran the circus, I would allow that.  I really find it annoying
that I have to add 3 useless lines of code (declare/begin/end) and an
extra level of indentation, when all I wanted to do was declare
a very-local object.

I also find it annoying that I can't add a statement at the beginning of
a procedure, without moving everything into a local block.  E.g. I have:

    procedure P (X : Integer) is
        Local : constant String := ...;
    begin
        ...

and I want add:

    if X = 0 then
        raise Blah;
    end if;

and I want that to come first.

> After all, with the possibility to initialize the new variable with
> arbitrarily complex expression (including function call), this is
> already the case and the whole declare-begin-end block is just
> reflecting some artificial separation.

I agree.  I suppose it comes from Pascal, where declarations and
executable code are completely separated.  It makes no sense in
Ada, where declarations are just as executable as statements.

- Bob



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08 21:19             ` Robert A Duff
@ 2008-06-09  7:14               ` Dmitry A. Kazakov
  2008-06-09  9:43                 ` Georg Bauhaus
  2008-06-15 19:38                 ` Robert A Duff
  2008-06-09 11:00               ` Georg Bauhaus
  1 sibling, 2 replies; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-09  7:14 UTC (permalink / raw)


On Sun, 08 Jun 2008 17:19:11 -0400, Robert A Duff wrote:

> Maciej Sobczak <see.my.homepage@gmail.com> writes:
> 
>> After all, with the possibility to initialize the new variable with
>> arbitrarily complex expression (including function call), this is
>> already the case and the whole declare-begin-end block is just
>> reflecting some artificial separation.
> 
> I agree.  I suppose it comes from Pascal, where declarations and
> executable code are completely separated.  It makes no sense in
> Ada, where declarations are just as executable as statements.

I disagree. I think it does make sense because it clearly defines the scope
of the declared variable. Expression (result) /= named object. And
reversely, if you don't need the variable, you are free to put expressions
anywhere outside the declaration part.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08 17:17               ` Niklas Holsti
@ 2008-06-09  7:26                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-09  7:26 UTC (permalink / raw)


On Sun, 08 Jun 2008 20:17:33 +0300, Niklas Holsti wrote:

> I agree that exception contracts would work in this example. Ok, 
> exception contracts would reveal some -- perhaps most -- of these 
> errors at compile time, but not all.

Nothing can reveal all errors.

But errors in exceptions became painful in Ada. I permanently run into the
stuff, like when an unhandled exception winds up controlled objects,
causing secondary exceptions in Finalizes (which may not happen if the
primary exception were handled). It is very difficult to trace back.

[...]
> I agree that an application could not *recover* from failures in 
> package elaboration. But the application could possibly fail more 
> gracefully, perhaps even continue operating in a degraded mode.

I think that partitions could be a better candidate for such things.

Maybe it is a "philosophy" again, but to me failed declarations is a
correctness problem, rather than an exceptional state. As such it should
not be handled inside itself.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-09  7:14               ` Dmitry A. Kazakov
@ 2008-06-09  9:43                 ` Georg Bauhaus
  2008-06-09 10:25                   ` Dmitry A. Kazakov
  2008-06-15 19:38                 ` Robert A Duff
  1 sibling, 1 reply; 38+ messages in thread
From: Georg Bauhaus @ 2008-06-09  9:43 UTC (permalink / raw)


Dmitry A. Kazakov schrieb:
> On Sun, 08 Jun 2008 17:19:11 -0400, Robert A Duff wrote:
> 
>> Maciej Sobczak <see.my.homepage@gmail.com> writes:
>>
>>> After all, with the possibility to initialize the new variable with
>>> arbitrarily complex expression (including function call), this is
>>> already the case and the whole declare-begin-end block is just
>>> reflecting some artificial separation.
>> I agree.  I suppose it comes from Pascal, where declarations and
>> executable code are completely separated.  It makes no sense in
>> Ada, where declarations are just as executable as statements.
> 
> I disagree. I think it does make sense because it clearly defines the scope
> of the declared variable.

Still, a somewhat *new* kind kind of handling exceptions in single
declarations looks interesting?

Given linear order of elaboration in declarative parts,
and thus the possibility of sequencing initialization
of local variables:

   procedure P is
      declare
         X1: constant T;  -- like Java final
      begin
         X1 := New_T(...);  -- may raise CE
      exception
         when Constraint_Error =>
             X1 := Fallback_T;  -- better than Java final
      end;
      X2: D := New_D(X1, ...);  -- safely refer to X1
   begin
      ...
   end P;



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-09  9:43                 ` Georg Bauhaus
@ 2008-06-09 10:25                   ` Dmitry A. Kazakov
  2008-06-09 10:42                     ` Sébastien Morand
  2008-06-09 11:43                     ` Georg Bauhaus
  0 siblings, 2 replies; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-09 10:25 UTC (permalink / raw)


On Mon, 09 Jun 2008 11:43:36 +0200, Georg Bauhaus wrote:

> Dmitry A. Kazakov schrieb:

>> On Sun, 08 Jun 2008 17:19:11 -0400, Robert A Duff wrote:
>> 
>>> Maciej Sobczak <see.my.homepage@gmail.com> writes:
>>>
>>>> After all, with the possibility to initialize the new variable with
>>>> arbitrarily complex expression (including function call), this is
>>>> already the case and the whole declare-begin-end block is just
>>>> reflecting some artificial separation.

>>> I agree.  I suppose it comes from Pascal, where declarations and
>>> executable code are completely separated.  It makes no sense in
>>> Ada, where declarations are just as executable as statements.

>> I disagree. I think it does make sense because it clearly defines the scope
>> of the declared variable.
 
> Still, a somewhat *new* kind kind of handling exceptions in single
> declarations looks interesting?

> Given linear order of elaboration in declarative parts,
> and thus the possibility of sequencing initialization
> of local variables:
> 
>    procedure P is
>       declare
>          X1: constant T;  -- like Java final
>       begin
>          X1 := New_T(...);  -- may raise CE
>       exception
>          when Constraint_Error =>
>              X1 := Fallback_T;  -- better than Java final
>       end;
>       X2: D := New_D(X1, ...);  -- safely refer to X1
>    begin
>       ...
>    end P;

Huh, if you want closures, just say so. There is no need to break proven
language concepts in order to have desired effect:

procedure P is
    X1: constant T := -- Here anonymous function literal begins
       function return T is
       begin
            return New_T (...);  -- may raise CE
       exception
          when Constraint_Error =>
              return Fallback_T;  -- better than Java final
       end;
   X2: D := New_D (X1, ...);  -- safely refer to X1
begin
   ...
end P;

Note, no magic stuff, no exception handlers in declarations, just a simple
thing, which Ada should have had from the day one: functional types and
literals of.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-09 10:25                   ` Dmitry A. Kazakov
@ 2008-06-09 10:42                     ` Sébastien Morand
  2008-06-09 11:43                     ` Georg Bauhaus
  1 sibling, 0 replies; 38+ messages in thread
From: Sébastien Morand @ 2008-06-09 10:42 UTC (permalink / raw)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Dmitry A. Kazakov a �crit :
> On Mon, 09 Jun 2008 11:43:36 +0200, Georg Bauhaus wrote:
> 
>> Dmitry A. Kazakov schrieb:
> 
>>> On Sun, 08 Jun 2008 17:19:11 -0400, Robert A Duff wrote:
>>>
>>>> Maciej Sobczak <see.my.homepage@gmail.com> writes:
>>>>
>>>>> After all, with the possibility to initialize the new variable with
>>>>> arbitrarily complex expression (including function call), this is
>>>>> already the case and the whole declare-begin-end block is just
>>>>> reflecting some artificial separation.
> 
>>>> I agree.  I suppose it comes from Pascal, where declarations and
>>>> executable code are completely separated.  It makes no sense in
>>>> Ada, where declarations are just as executable as statements.
> 
>>> I disagree. I think it does make sense because it clearly defines the scope
>>> of the declared variable.
>  
>> Still, a somewhat *new* kind kind of handling exceptions in single
>> declarations looks interesting?
> 
>> Given linear order of elaboration in declarative parts,
>> and thus the possibility of sequencing initialization
>> of local variables:
>>
>>    procedure P is
>>       declare
>>          X1: constant T;  -- like Java final
>>       begin
>>          X1 := New_T(...);  -- may raise CE
>>       exception
>>          when Constraint_Error =>
>>              X1 := Fallback_T;  -- better than Java final
>>       end;
>>       X2: D := New_D(X1, ...);  -- safely refer to X1
>>    begin
>>       ...
>>    end P;
> 
> Huh, if you want closures, just say so. There is no need to break proven
> language concepts in order to have desired effect:
> 
> procedure P is
>     X1: constant T := -- Here anonymous function literal begins
>        function return T is
>        begin
>             return New_T (...);  -- may raise CE
>        exception
>           when Constraint_Error =>
>               return Fallback_T;  -- better than Java final
>        end;
>    X2: D := New_D (X1, ...);  -- safely refer to X1
> begin
>    ...
> end P;
> 
> Note, no magic stuff, no exception handlers in declarations, just a simple
> thing, which Ada should have had from the day one: functional types and
> literals of.

You can do that but not in an anonymous way, so what's the point? I
think it not a good practive to use anonymous function or procedure, it
makes hard to read code (and it's one of the feature of ada: easy to read)

I prefer this kind of writing:
procedure P is

   function Init_T return T;

   function Init_T return T is
   begin
       return New_T (...);  -- may raise CE
   exception
     when Constraint_Error =>
        return Fallback_T;  -- better than Java final
   end;

   X1: constant T := Init_T; -- Here anonymous function literal begins
   X2: D := New_D (X1, ...);  -- safely refer to X1

begin
   ...
end P;
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)

iD8DBQFITQkK+zV9xm4PlDQRAnhxAJ9FKGI7aVenIlDrrnsl3LHJE42FJQCfV9lc
Vvl0CozDP7p/Ah44Ivnz4G8=
=bdGO
-----END PGP SIGNATURE-----



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-08 21:19             ` Robert A Duff
  2008-06-09  7:14               ` Dmitry A. Kazakov
@ 2008-06-09 11:00               ` Georg Bauhaus
  2008-06-09 14:27                 ` Britt Snodgrass
  2008-06-15 19:48                 ` Robert A Duff
  1 sibling, 2 replies; 38+ messages in thread
From: Georg Bauhaus @ 2008-06-09 11:00 UTC (permalink / raw)


Robert A Duff schrieb:
> Maciej Sobczak <see.my.homepage@gmail.com> writes:
> 
>> You did not state it explicitly, but I presume that you allow mixing
>> declarations with executable code ("as in Java and other languages")?
> 
> Yes, if I ran the circus, I would allow that.  I really find it annoying
> that I have to add 3 useless lines of code (declare/begin/end) and an
> extra level of indentation, when all I wanted to do was declare
> a very-local object.

I find it annoying when I have to search other people's
procedures for variables. A typical sequence of statements is
sprinkled with declarations (Java, C, Perl, ...) and no oher
indication of the newly introduced variables other than
two identifiers before "=" or ";".

As Dmitry says, there is an *implicit* scope only.
When I'm up the wall I speculate whether this viewpoint on language
use is driven by a desire to achieve income by obfuscation?
The tempting quick hack?

To me,  ad hoc variables between statements and Java classes fully
named in source but without "import" at the head of the source file
are similar in character.

The good news is: computers can help us with getting the
necessary "paper work" (declare block etc.) done; use a
good editor.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-09 10:25                   ` Dmitry A. Kazakov
  2008-06-09 10:42                     ` Sébastien Morand
@ 2008-06-09 11:43                     ` Georg Bauhaus
  2008-06-09 12:03                       ` Dmitry A. Kazakov
  1 sibling, 1 reply; 38+ messages in thread
From: Georg Bauhaus @ 2008-06-09 11:43 UTC (permalink / raw)


Dmitry A. Kazakov schrieb:

>> Given linear order of elaboration in declarative parts,
>> and thus the possibility of sequencing initialization
>> of local variables:
>>
>>    procedure P is
>>       declare
>>          X1: constant T;  -- like Java final
>>       begin
>>          X1 := New_T(...);  -- may raise CE
>>       exception
>>          when Constraint_Error =>
>>              X1 := Fallback_T;  -- better than Java final
>>       end;
>>       X2: D := New_D(X1, ...);  -- safely refer to X1
>>    begin
>>       ...
>>    end P;
> 
> Huh, if you want closures, just say so. There is no need to break proven
> language concepts in order to have desired effect:

I should have said that the scope of X1 extends beyond
the declare block (which I had stupidly chosen as key words).

> procedure P is
>     X1: constant T := -- Here anonymous function literal begins
>        function return T is
>        begin
>             return New_T (...);  -- may raise CE
>        exception
>           when Constraint_Error =>
>               return Fallback_T;  -- better than Java final
>        end;
>    X2: D := New_D (X1, ...);  -- safely refer to X1
> begin
>    ...
> end P;


Why closures? I was about to mention nesting, which
solves this issue in Ada 95 and Ada:

procedure P is
    function Safe_T return T is
    begin
       return New_T (...);  -- may raise CE
    exception
       when Constraint_Error =>
          return Fallback_T;  -- better than Java final
    end;
    X1: constant T := Safe_T;

    X2: D := New_D (X1, ...);  -- safely refer to X1
begin
    ...
end P;

In a sense, Safe_T works just like constructors that don't raise.


> Note, no magic stuff, no exception handlers in declarations, just a simple
> thing, which Ada should have had from the day one: functional types and
> literals of.

With the function's full environment?



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-09 11:43                     ` Georg Bauhaus
@ 2008-06-09 12:03                       ` Dmitry A. Kazakov
  0 siblings, 0 replies; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-09 12:03 UTC (permalink / raw)


On Mon, 09 Jun 2008 13:43:21 +0200, Georg Bauhaus wrote:

> Why closures? I was about to mention nesting, which
> solves this issue in Ada 95 and Ada:

[...]

Only to show what the thing is. [Nested function is a closure too.]

> In a sense, Safe_T works just like constructors that don't raise.

Yes, fail-safe declarations do not raise (per definition).

>> Note, no magic stuff, no exception handlers in declarations, just a simple
>> thing, which Ada should have had from the day one: functional types and
>> literals of.
> 
> With the function's full environment?

Just usual stuff where access type (or a formal generic subprogram) is
presently used instead.

Certainly, no upward closures. So all accessibility checks would apply.
I.e. you would not be able to return a local subprogram.[*]

------------
* Unless [which is a another IMO necessary step] the subprograms is
conditionally pure relatively to the result's type scope.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-09 11:00               ` Georg Bauhaus
@ 2008-06-09 14:27                 ` Britt Snodgrass
  2008-06-15 19:50                   ` Robert A Duff
  2008-06-15 19:48                 ` Robert A Duff
  1 sibling, 1 reply; 38+ messages in thread
From: Britt Snodgrass @ 2008-06-09 14:27 UTC (permalink / raw)


On Jun 9, 6:00 am, Georg Bauhaus <rm.dash-bauh...@futureapps.de>
wrote:
> Robert A Duff schrieb:
>
> > Maciej Sobczak <see.my.homep...@gmail.com> writes:
>
> >> You did not state it explicitly, but I presume that you allow mixing
> >> declarations with executable code ("as in Java and other languages")?
>
> > Yes, if I ran the circus, I would allow that.  I really find it annoying
> > that I have to add 3 useless lines of code (declare/begin/end) and an
> > extra level of indentation, when all I wanted to do was declare
> > a very-local object.
>
> I find it annoying when I have to search other people's
> procedures for variables. A typical sequence of statements is
> sprinkled with declarations (Java, C, Perl, ...) and no oher
> indication of the newly introduced variables other than
> two identifiers before "=" or ";".
>
> As Dmitry says, there is an *implicit* scope only.
> When I'm up the wall I speculate whether this viewpoint on language
> use is driven by a desire to achieve income by obfuscation?
> The tempting quick hack?
>
> To me,  ad hoc variables between statements and Java classes fully
> named in source but without "import" at the head of the source file
> are similar in character.
>
> The good news is: computers can help us with getting the
> necessary "paper work" (declare block etc.) done; use a
> good editor.

I very much agree. The requirement for an explicit declaritive region
is a very good thing for reasons of readability and maintainability.
If variables could be declared anywhere in a procedure then it really
would be a circus.

- Britt



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-09  7:14               ` Dmitry A. Kazakov
  2008-06-09  9:43                 ` Georg Bauhaus
@ 2008-06-15 19:38                 ` Robert A Duff
  2008-06-15 20:52                   ` Dmitry A. Kazakov
  1 sibling, 1 reply; 38+ messages in thread
From: Robert A Duff @ 2008-06-15 19:38 UTC (permalink / raw)


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

> On Sun, 08 Jun 2008 17:19:11 -0400, Robert A Duff wrote:
>
>> Maciej Sobczak <see.my.homepage@gmail.com> writes:
>> 
>>> After all, with the possibility to initialize the new variable with
>>> arbitrarily complex expression (including function call), this is
>>> already the case and the whole declare-begin-end block is just
>>> reflecting some artificial separation.
>> 
>> I agree.  I suppose it comes from Pascal, where declarations and
>> executable code are completely separated.  It makes no sense in
>> Ada, where declarations are just as executable as statements.
>
> I disagree. I think it does make sense because it clearly defines the scope
> of the declared variable. Expression (result) /= named object. And
> reversely, if you don't need the variable, you are free to put expressions
> anywhere outside the declaration part.

If Ada allowed:

    for I in A'Range loop
        X : constant Character := F(A(I)); -- Not Ada!
        Do_Something(X);
    end loop;

the scope of X is clear -- it's the entire loop body.

    for I in A'Range loop
        declare
            X : constant Character := F(A(I));
        begin
            Do_Something(X);
        end;
    end loop;

does not clarify (in my opinion).  It just adds noise.

You could still say:

    for I in A'Range loop
        begin
            X : constant Character := F(A(I)); -- Not Ada!
            Do_Something(X);
        end;
        Do_Something_Else;
    end loop;

in my circus, if you want to further limit the scope of X
(to smaller than the whole loop body).

- Bob



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-09 11:00               ` Georg Bauhaus
  2008-06-09 14:27                 ` Britt Snodgrass
@ 2008-06-15 19:48                 ` Robert A Duff
  1 sibling, 0 replies; 38+ messages in thread
From: Robert A Duff @ 2008-06-15 19:48 UTC (permalink / raw)


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

> Robert A Duff schrieb:
>> Maciej Sobczak <see.my.homepage@gmail.com> writes:
>>
>>> You did not state it explicitly, but I presume that you allow mixing
>>> declarations with executable code ("as in Java and other languages")?
>> Yes, if I ran the circus, I would allow that.  I really find it
>> annoying
>> that I have to add 3 useless lines of code (declare/begin/end) and an
>> extra level of indentation, when all I wanted to do was declare
>> a very-local object.
>
> I find it annoying when I have to search other people's
> procedures for variables. A typical sequence of statements is
> sprinkled with declarations (Java, C, Perl, ...) and no oher
> indication of the newly introduced variables other than
> two identifiers before "=" or ";".

I suppose it's a matter of taste, at least in part.

But the situation in C-style languages is different -- declarations
don't stand out very well.  In Ada, the declaration syntax is clear
enough without adding "declare/begin/end".

Besides, even with "declare/begin/end", you still have to search all
over the place to find declarations -- they can be in various packages,
and in any outer block, procedure, etc.

> As Dmitry says, there is an *implicit* scope only.
> When I'm up the wall I speculate whether this viewpoint on language
> use is driven by a desire to achieve income by obfuscation?
> The tempting quick hack?

Not at all.  IMHO, "declare/begin/end" obfuscates, by pretending that
the stuff between declare and begin is just declarations, no executable
code.

> To me,  ad hoc variables between statements and Java classes fully
> named in source but without "import" at the head of the source file
> are similar in character.

They seem completely different, to me.  I agree with you that importing
without saying so up front is not good.

> The good news is: computers can help us with getting the
> necessary "paper work" (declare block etc.) done; use a
> good editor.

Sure, I do use a good editor.  That's not the point -- I'm not
complaining about how much work it is to type in "declare/begin/end" --
I'm complaining about how much work it is to _read_ that extra clutter.
The blocks of code we're talking about are often just 2 or 3 lines
of code, so adding several nested declare blocks can easily double
the size of the procedure.

- Bob



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-09 14:27                 ` Britt Snodgrass
@ 2008-06-15 19:50                   ` Robert A Duff
  0 siblings, 0 replies; 38+ messages in thread
From: Robert A Duff @ 2008-06-15 19:50 UTC (permalink / raw)


Britt Snodgrass <britt.snodgrass@gmail.com> writes:

> I very much agree. The requirement for an explicit declaritive region
> is a very good thing for reasons of readability and maintainability.
> If variables could be declared anywhere in a procedure then it really
> would be a circus.

But you have not explained why you think declare blocks aid readability
and maintainability.  I don't think they do.  Is it just a matter of
taste, or a matter of what one is used to?

- Bob



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-15 19:38                 ` Robert A Duff
@ 2008-06-15 20:52                   ` Dmitry A. Kazakov
  2008-06-15 22:06                     ` Robert A Duff
  0 siblings, 1 reply; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-15 20:52 UTC (permalink / raw)


On Sun, 15 Jun 2008 15:38:08 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Sun, 08 Jun 2008 17:19:11 -0400, Robert A Duff wrote:
>>
>>> I agree.  I suppose it comes from Pascal, where declarations and
>>> executable code are completely separated.  It makes no sense in
>>> Ada, where declarations are just as executable as statements.
>>
>> I disagree. I think it does make sense because it clearly defines the scope
>> of the declared variable. Expression (result) /= named object. And
>> reversely, if you don't need the variable, you are free to put expressions
>> anywhere outside the declaration part.
> 
> If Ada allowed:
> 
>     for I in A'Range loop
>         X : constant Character := F(A(I)); -- Not Ada!
>         Do_Something(X);
>     end loop;
>
> the scope of X is clear -- it's the entire loop body.

No, then it should better be something like:

   for I in A'Range;
        X : constant Character := F(A(I)); -- Not Ada!
   loop
      Do_Something(X);
   end loop;

The declarative part of a loop is between "for" and "loop."

However I find nested declare/begin/end more readable because it clearly
disambiguates between the scope of the loop and the scope of one iteration
of.

> You could still say:
> 
>     for I in A'Range loop
>         begin
>             X : constant Character := F(A(I)); -- Not Ada!
>             Do_Something(X);
>         end;
>         Do_Something_Else;
>     end loop;

But what would happen if I said:

   begin
      raise Foo_Error;
      X : constant Character := F(A(I)); -- Not Ada!
      Do_Something (X);
   exception
      when Foo_Error =>
         Do_Something_Interesting (X);
   end;

---------------
What I miss is things like:

procedure Foo (X : T'Class) is
begin
   case X is
      when S_X : S'Class =>
          Do_S_Method (S_X);
      when others =>
          Do_Something_Else;
   end case;
end Foo;

procedure Bar (Ptr : access T'Class) is
begin
   case Ptr is
      when Ref : not null access T =>
          Ref.Foo; -- No more checks
      when others =>
          null;
   end case;
end Bar;

case I is
   when Checked_I : A'Range =>
      ... A (Checked_I) ... -- No range checks
   ...
end case;

case L - 123 is
   when Sum : Positive =>
       -- Sum = L - 123 and it is positive
       ...
   when Sum : Integer =>
       -- Sum = L - 123 and it is not positive
      ...
   when others =>
       -- It would overflow, but no exception was propagated
      ...
end case;

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-15 20:52                   ` Dmitry A. Kazakov
@ 2008-06-15 22:06                     ` Robert A Duff
  2008-06-16  8:31                       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 38+ messages in thread
From: Robert A Duff @ 2008-06-15 22:06 UTC (permalink / raw)


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

> On Sun, 15 Jun 2008 15:38:08 -0400, Robert A Duff wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>> On Sun, 08 Jun 2008 17:19:11 -0400, Robert A Duff wrote:
>>>
>>>> I agree.  I suppose it comes from Pascal, where declarations and
>>>> executable code are completely separated.  It makes no sense in
>>>> Ada, where declarations are just as executable as statements.
>>>
>>> I disagree. I think it does make sense because it clearly defines the scope
>>> of the declared variable. Expression (result) /= named object. And
>>> reversely, if you don't need the variable, you are free to put expressions
>>> anywhere outside the declaration part.
>> 
>> If Ada allowed:
>> 
>>     for I in A'Range loop
>>         X : constant Character := F(A(I)); -- Not Ada!
>>         Do_Something(X);
>>     end loop;
>>
>> the scope of X is clear -- it's the entire loop body.
>
> No, then it should better be something like:
>
>    for I in A'Range;
>         X : constant Character := F(A(I)); -- Not Ada!
>    loop
>       Do_Something(X);
>    end loop;
>
> The declarative part of a loop is between "for" and "loop."

I don't see why a loop needs a declarative part.
My idea is that every statement list is a scope.

> However I find nested declare/begin/end more readable because it clearly
> disambiguates between the scope of the loop and the scope of one iteration
> of.

I don't get it.  You declare something inside a loop body, or the 'then'
part of an 'if' -- it's local to that.

>> You could still say:
>> 
>>     for I in A'Range loop
>>         begin
>>             X : constant Character := F(A(I)); -- Not Ada!
>>             Do_Something(X);
>>         end;
>>         Do_Something_Else;
>>     end loop;
>
> But what would happen if I said:
>
>    begin
>       raise Foo_Error;
>       X : constant Character := F(A(I)); -- Not Ada!
>       Do_Something (X);
>    exception
>       when Foo_Error =>
>          Do_Something_Interesting (X);
>    end;

As I said earlier, exception-handler regions deserve their own syntax,
not connected with declaration blocks.

> ---------------
> What I miss is things like:

Not sure how these are related to local decls...

> procedure Foo (X : T'Class) is
> begin
>    case X is
>       when S_X : S'Class =>
>           Do_S_Method (S_X);
>       when others =>
>           Do_Something_Else;
>    end case;
> end Foo;
>
> procedure Bar (Ptr : access T'Class) is
> begin
>    case Ptr is
>       when Ref : not null access T =>
>           Ref.Foo; -- No more checks
>       when others =>
>           null;
>    end case;
> end Bar;
>
> case I is
>    when Checked_I : A'Range =>
>       ... A (Checked_I) ... -- No range checks
>    ...
> end case;
>
> case L - 123 is
>    when Sum : Positive =>
>        -- Sum = L - 123 and it is positive
>        ...
>    when Sum : Integer =>
>        -- Sum = L - 123 and it is not positive
>       ...
>    when others =>
>        -- It would overflow, but no exception was propagated
>       ...
> end case;

- Bob



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-15 22:06                     ` Robert A Duff
@ 2008-06-16  8:31                       ` Dmitry A. Kazakov
  2008-06-16 19:17                         ` Robert A Duff
  0 siblings, 1 reply; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-16  8:31 UTC (permalink / raw)


On Sun, 15 Jun 2008 18:06:00 -0400, Robert A Duff wrote:

> I don't see why a loop needs a declarative part.
> My idea is that every statement list is a scope.

What is so special in statement lists? Pushing this idea further, we should
also conclude that any sequence of expressions is a scope. For example, an
aggregate:

String'(X : constant Character := F(A(I)), 1 => X, 2 => 'a', 3 => X);

a function call etc.

[ That might be useful to overcome some silly limitations on discriminants:

type T (S : Storage_Count) is record
-- Buffer : Storage_Elements_Array (0..S-1);  -- This would be illegal, so
   Buffer : Storage_Elements_Array
      (Last : constant Storage_Offset := S-1, 0..Last);
end record; ]

>> However I find nested declare/begin/end more readable because it clearly
>> disambiguates between the scope of the loop and the scope of one iteration
>> of.
> 
> I don't get it.  You declare something inside a loop body, or the 'then'
> part of an 'if' -- it's local to that.

Local in which sense? There are statical nesting and dynamic execution of
the loop body upon iterations. It is not obvious (rather counterintuitive)
that declarations have to be "executed." To me the purpose of Ada's
"declare" was merely in conversion of "elaboration" to "execution."

>> But what would happen if I said:
>>
>>    begin
>>       raise Foo_Error;
>>       X : constant Character := F(A(I)); -- Not Ada!
>>       Do_Something (X);
>>    exception
>>       when Foo_Error =>
>>          Do_Something_Interesting (X);
>>    end;

> As I said earlier, exception-handler regions deserve their own syntax,
> not connected with declaration blocks.

So an exception handler attached to the statement list will see nothing
from the scope of the list? I.e. everything in the list will be wound up
before the handler gets fired. Then you would need additional nesting if
you wished to handle exceptions from that list. Here we go:

   X : constant ...;
   Y : constant ...;
   begin
      Do_Something (X, Y);
   exception
      when Foo_Error =>
          Do_Something_Interesting (X, Y);
   end;

What is the gain? Just add "declare" in front of this and it becomes legal
Ada.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-16  8:31                       ` Dmitry A. Kazakov
@ 2008-06-16 19:17                         ` Robert A Duff
  2008-06-16 20:30                           ` Dmitry A. Kazakov
  2008-06-16 22:02                           ` Georg Bauhaus
  0 siblings, 2 replies; 38+ messages in thread
From: Robert A Duff @ 2008-06-16 19:17 UTC (permalink / raw)


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

> On Sun, 15 Jun 2008 18:06:00 -0400, Robert A Duff wrote:
>
>> I don't see why a loop needs a declarative part.
>> My idea is that every statement list is a scope.
>
> What is so special in statement lists? Pushing this idea further, we should
> also conclude that any sequence of expressions is a scope. For example, an
> aggregate:
>
> String'(X : constant Character := F(A(I)), 1 => X, 2 => 'a', 3 => X);
>
> a function call etc.

Well, I suppose something like that could work, but it seems like it
would be confusing -- how many components are there, which pieces of
text belong to which components (or which parameters, in the function
call case)?

> [ That might be useful to overcome some silly limitations on discriminants:
>
> type T (S : Storage_Count) is record
> -- Buffer : Storage_Elements_Array (0..S-1);  -- This would be illegal, so
>    Buffer : Storage_Elements_Array
>       (Last : constant Storage_Offset := S-1, 0..Last);
> end record; ]

I don't see the point.  Why not just make it legal (the line marked
"This would be illegal").  Rules would be needed about when to evaluate
that expression -- presumably on elaboration of a discriminant
constraint, or an aggregate, or a discriminant default.  I don't think
having a name for Last makes this any easier.

>>> However I find nested declare/begin/end more readable because it clearly
>>> disambiguates between the scope of the loop and the scope of one iteration
>>> of.
>> 
>> I don't get it.  You declare something inside a loop body, or the 'then'
>> part of an 'if' -- it's local to that.
>
> Local in which sense? There are statical nesting and dynamic execution of
> the loop body upon iterations.

The same sense as declare blocks.  That is, in my "circus",
this:

    ... loop
        <decls>
        <statements>
    end loop;

has identical semantics to:

    ... loop
        declare
            <decls>
        begin
            <statements>
        end;
    end loop;

The <decls> are elaborated each time through the loop.
(I can't imagine what _else_ it might mean!)

>...It is not obvious (rather counterintuitive)
> that declarations have to be "executed."

Well, it's a fundamental aspect of Ada, so Ada programmers have to get
used to it, even if they find it counterintuitive at first.

>...To me the purpose of Ada's
> "declare" was merely in conversion of "elaboration" to "execution."
>
>>> But what would happen if I said:
>>>
>>>    begin
>>>       raise Foo_Error;
>>>       X : constant Character := F(A(I)); -- Not Ada!
>>>       Do_Something (X);
>>>    exception
>>>       when Foo_Error =>
>>>          Do_Something_Interesting (X);
>>>    end;
>
>> As I said earlier, exception-handler regions deserve their own syntax,
>> not connected with declaration blocks.
>
> So an exception handler attached to the statement list will see nothing
> from the scope of the list? I.e. everything in the list will be wound up
> before the handler gets fired. Then you would need additional nesting if
> you wished to handle exceptions from that list. Here we go:
>
>    X : constant ...;
>    Y : constant ...;
>    begin
>       Do_Something (X, Y);
>    exception
>       when Foo_Error =>
>           Do_Something_Interesting (X, Y);
>    end;
>
> What is the gain? Just add "declare" in front of this and it becomes legal
> Ada.

That's where this conversation started: If you add "declare" above,
you get confusing syntax -- it looks like the exception handler handles
exceptions during the elab of X and Y, but it does not.
That's why I think it would be better to have a separate
"handle" statement.

- Bob



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-16 19:17                         ` Robert A Duff
@ 2008-06-16 20:30                           ` Dmitry A. Kazakov
  2008-06-16 22:02                           ` Georg Bauhaus
  1 sibling, 0 replies; 38+ messages in thread
From: Dmitry A. Kazakov @ 2008-06-16 20:30 UTC (permalink / raw)


On Mon, 16 Jun 2008 15:17:15 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Sun, 15 Jun 2008 18:06:00 -0400, Robert A Duff wrote:
>>
>>> I don't see why a loop needs a declarative part.
>>> My idea is that every statement list is a scope.
>>
>> What is so special in statement lists? Pushing this idea further, we should
>> also conclude that any sequence of expressions is a scope. For example, an
>> aggregate:
>>
>> String'(X : constant Character := F(A(I)), 1 => X, 2 => 'a', 3 => X);
>>
>> a function call etc.
> 
> Well, I suppose something like that could work, but it seems like it
> would be confusing -- how many components are there, which pieces of
> text belong to which components (or which parameters, in the function
> call case)?

Right, and to me declarations intermixed with statements look similarly
confusing.

>> [ That might be useful to overcome some silly limitations on discriminants:
>>
>> type T (S : Storage_Count) is record
>> -- Buffer : Storage_Elements_Array (0..S-1);  -- This would be illegal, so
>>    Buffer : Storage_Elements_Array
>>       (Last : constant Storage_Offset := S-1, 0..Last);
>> end record; ]
> 
> I don't see the point.  Why not just make it legal (the line marked
> "This would be illegal").

Well, maybe because it wasn't made since 1983? (:-))

> Rules would be needed about when to evaluate
> that expression -- presumably on elaboration of a discriminant
> constraint, or an aggregate, or a discriminant default.  I don't think
> having a name for Last makes this any easier.

It would be a "big" change and with it small ones could also get through...
(:-))

>>>> However I find nested declare/begin/end more readable because it clearly
>>>> disambiguates between the scope of the loop and the scope of one iteration
>>>> of.
>>> 
>>> I don't get it.  You declare something inside a loop body, or the 'then'
>>> part of an 'if' -- it's local to that.
>>
>> Local in which sense? There are statical nesting and dynamic execution of
>> the loop body upon iterations.
> 
> The same sense as declare blocks.  That is, in my "circus",
> this:
> 
>     ... loop
>         <decls>
>         <statements>
>     end loop;
> 
> has identical semantics to:
> 
>     ... loop
>         declare
>             <decls>
>         begin
>             <statements>
>         end;
>     end loop;
> 
> The <decls> are elaborated each time through the loop.
> (I can't imagine what _else_ it might mean!)

An invariant elaborated once for all iterations.

The mental block people like me have is that declarations are neither
statements nor operators. So an iteration does not iterate declarations. Or
better to say, the effect of n iterations is same as one of n+1 iterations.
It is still the same thing pronounced several times: A and A = A.

Making a declaration statement should consequently allow this:

   X : Integer := 1;
   Foo (X);
   X : Float := 2.0;
   Boo (X);

If it is just a statement, why can't I re-execute it?

>>> As I said earlier, exception-handler regions deserve their own syntax,
>>> not connected with declaration blocks.
>>
>> So an exception handler attached to the statement list will see nothing
>> from the scope of the list? I.e. everything in the list will be wound up
>> before the handler gets fired. Then you would need additional nesting if
>> you wished to handle exceptions from that list. Here we go:
>>
>>    X : constant ...;
>>    Y : constant ...;
>>    begin
>>       Do_Something (X, Y);
>>    exception
>>       when Foo_Error =>
>>           Do_Something_Interesting (X, Y);
>>    end;
>>
>> What is the gain? Just add "declare" in front of this and it becomes legal
>> Ada.
> 
> That's where this conversation started: If you add "declare" above,
> you get confusing syntax -- it looks like the exception handler handles
> exceptions during the elab of X and Y, but it does not.
> That's why I think it would be better to have a separate
> "handle" statement.

But "handle" would be still confusing:

handle
   X : constant ...;
   Y : constant ...;
   Do_Something (X, Y);
exception
   when Foo_Error =>
      Do_Something_Interesting (X, Y); -- Illegal
end;

There is no obvious way to mix declarations and statements being able to
handle exceptions from both at the same level.

Maybe I could explain why I don't enjoy the "performance" in another way.
In my eyes declarations have a "declared" persistent effect. It is a name
bound to some new object and the object itself. Statements don't have such
effects.

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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-16 19:17                         ` Robert A Duff
  2008-06-16 20:30                           ` Dmitry A. Kazakov
@ 2008-06-16 22:02                           ` Georg Bauhaus
  2008-06-16 23:04                             ` Robert A Duff
  1 sibling, 1 reply; 38+ messages in thread
From: Georg Bauhaus @ 2008-06-16 22:02 UTC (permalink / raw)


Robert A Duff wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Sun, 15 Jun 2008 18:06:00 -0400, Robert A Duff wrote:
>>
>>> I don't see why a loop needs a declarative part.
>>> My idea is that every statement list is a scope.
>> What is so special in statement lists? Pushing this idea further, we should
>> also conclude that any sequence of expressions is a scope. For example, an
>> aggregate:
>>
>> String'(X : constant Character := F(A(I)), 1 => X, 2 => 'a', 3 => X);
>>
>> a function call etc.
> 
> Well, I suppose something like that could work, but it seems like it
> would be confusing -- how many components are there, which pieces of
> text belong to which components (or which parameters, in the function
> call case)?
> 
>> [ That might be useful to overcome some silly limitations on discriminants:
>>
>> type T (S : Storage_Count) is record
>> -- Buffer : Storage_Elements_Array (0..S-1);  -- This would be illegal, so
>>    Buffer : Storage_Elements_Array
>>       (Last : constant Storage_Offset := S-1, 0..Last);
>> end record; ]
> 
> I don't see the point.  Why not just make it legal (the line marked
> "This would be illegal").  Rules would be needed about when to evaluate
> that expression -- presumably on elaboration of a discriminant
> constraint, or an aggregate, or a discriminant default.  I don't think
> having a name for Last makes this any easier.
> 
>>>> However I find nested declare/begin/end more readable because it clearly
>>>> disambiguates between the scope of the loop and the scope of one iteration
>>>> of.
>>> I don't get it.  You declare something inside a loop body, or the 'then'
>>> part of an 'if' -- it's local to that.
>> Local in which sense? There are statical nesting and dynamic execution of
>> the loop body upon iterations.
> 
> The same sense as declare blocks.  That is, in my "circus",
> this:
> 
>     ... loop
>         <decls>
>         <statements>
>     end loop;


   ... loop
      Get(Buffer(K));
      <decls>   -- depending on Buffer
      <statements>
   end loop;

I guess that in order to maintain the order(?)
SCOPE [DECLS] STATEMENTS END-SCOPE
we would be needing

   ... loop
      Get(Initial(K));
      begin
         <decls>
         <statements>
      end;
   end loop;

> has identical semantics to:
> 
>     ... loop
>         declare
>             <decls>
>         begin
>             <statements>
>         end;
>     end loop;

   ... loop
      Get(Buffer(K));
      declare
         <decls>
      begin
         <statements>
      end;
   end loop;

Compared to the solution above, that would be an exchange
of BEGIN <-> DECLARE and the addition of a BEGIN where there
is nothing between <decls> and <statements> above.

A quick shot at syntax, what impact does this have, if any?
I'm adding a few rather artificial errors, but nevertheless:

   ... scope
      function Foo(N: Integer := K);
      return Value;
   end scope;

   ... scope
      declare
         function Foo(N: Integer := K);
         return Value;
      begin
         null;
      end;
   end scope;

By no more than a gut feeling I'd say that from a syntax
point of view, the omission of explicit declare blocks
adds a few more opportunities for ambiguity: RETURN is
at least not likely introducing a statement in the second
example.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: About String
  2008-06-16 22:02                           ` Georg Bauhaus
@ 2008-06-16 23:04                             ` Robert A Duff
  0 siblings, 0 replies; 38+ messages in thread
From: Robert A Duff @ 2008-06-16 23:04 UTC (permalink / raw)


Georg Bauhaus <rm.tsoh.plus-bug.bauhaus@maps.futureapps.de> writes:

> A quick shot at syntax, what impact does this have, if any?

It doesn't work at all, syntactically, assuming you want to remain
compatible with Ada.  The whole idea is pure fantasy!  ;-)

- Bob



^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2008-06-16 23:04 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-06 17:29 About String Sébastien Morand
2008-06-07 16:18 ` Simon Wright
2008-06-07 17:01   ` Pascal Obry
2008-06-07 22:13     ` Chris Moore
2008-06-08  6:47       ` Niklas Holsti
2008-06-08  7:35         ` Dmitry A. Kazakov
2008-06-08 10:29           ` Sebastien Morand
2008-06-08 10:53             ` Dmitry A. Kazakov
2008-06-08 11:14           ` Niklas Holsti
2008-06-08 13:16             ` Dmitry A. Kazakov
2008-06-08 17:17               ` Niklas Holsti
2008-06-09  7:26                 ` Dmitry A. Kazakov
2008-06-08 11:48           ` Martin
2008-06-08 13:17             ` Conditional declarations (was: About String) Dmitry A. Kazakov
2008-06-08 18:26           ` About String Chris Moore
2008-06-08 18:32         ` Robert A Duff
2008-06-08 20:51           ` Maciej Sobczak
2008-06-08 21:19             ` Robert A Duff
2008-06-09  7:14               ` Dmitry A. Kazakov
2008-06-09  9:43                 ` Georg Bauhaus
2008-06-09 10:25                   ` Dmitry A. Kazakov
2008-06-09 10:42                     ` Sébastien Morand
2008-06-09 11:43                     ` Georg Bauhaus
2008-06-09 12:03                       ` Dmitry A. Kazakov
2008-06-15 19:38                 ` Robert A Duff
2008-06-15 20:52                   ` Dmitry A. Kazakov
2008-06-15 22:06                     ` Robert A Duff
2008-06-16  8:31                       ` Dmitry A. Kazakov
2008-06-16 19:17                         ` Robert A Duff
2008-06-16 20:30                           ` Dmitry A. Kazakov
2008-06-16 22:02                           ` Georg Bauhaus
2008-06-16 23:04                             ` Robert A Duff
2008-06-09 11:00               ` Georg Bauhaus
2008-06-09 14:27                 ` Britt Snodgrass
2008-06-15 19:50                   ` Robert A Duff
2008-06-15 19:48                 ` Robert A Duff
2008-06-08 11:13     ` Simon Wright
2008-06-08 19:03       ` Sebastien Morand

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