comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: advice on package design
Date: Mon, 21 Mar 2005 19:16:16 +0100
Date: 2005-03-21T19:16:17+01:00	[thread overview]
Message-ID: <1ffju2fe4dqmz$.10w4bxtx2kvs6$.dlg@40tude.net> (raw)
In-Reply-To: wccd5ttezxj.fsf@shell01.TheWorld.com

On 21 Mar 2005 11:17:28 -0500, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On 17 Mar 2005 16:26:22 -0500, Robert A Duff wrote:
>> 
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>> 
>>>> I like the separation very much.
>>> 
>>> You're not alone.
>>> 
>>> Part of my reason is that declarations in Ada execute code at run time.
>>> In other languages (e.g. Pascal) there is a strict separation:
>>> declarations declare, statements execute, so it makes sense to have
>>> a syntactic line drawn between the two.  But in Ada, the decls can
>>> do real work, so the line drawn by the "begin" is misleading.
>> 
>> Yes, indirectly they do. For the following body this is the code that never
>> fail. Similarly, each "end;" is in fact also a code which again never fails
>> (for the body above). I can buy this as modularization (can I sell it so
>> too? (:-))
> 
> The problem is that whether something goes above or below the "begin"
> depends on all kinds of extraneous factors.  If I want to initialize a
> variable with a function, it goes above the line.  If I want to use
> a procedure call, or a loop, it goes below the line.  Etc.

The effects of the declaration of an initialized variable and of a
procedure call are fundamentally different. The first creates a new object
for following scope. Evaluation of that object is rather a side effect. All
things visible within the scope should be elaborated before "begin". What
if I rename "declare" to "require", i.e. consider the declaration block as
a precondition for following "begin". Will it look logical then?

require
   X : T := ...;
begin
   -- do something with X
end; -- ensure that there is no X anymore

The problem and difference with a procedure call is that it has no visible
effect. If it had, then that could be put in the declaration block.

>>> In some cases, the decls do *all* the work, especially when you're
>>> working with Strings, where the length usually depends on the 
>>> initial value.  Then the procedure body says "null;", meaning
>>> "this does nothing", which is a lie.
>> 
>> Yes. A similar case is:
>> 
>> if 0 = Some_Win_API (...) then
>>    null; -- Don't care about your silly return codes!
>> end if;
> 
> It doesn't seem similar to me.  Here, we are explicitly saying that the
> "then" part does nothing, and that's a good thing. 

But the only effect of Some_Win_API is its side effect. Using if-then-else
here is as misleading as null body of a procedure. It could even be written
as such a procedure!

procedure Some_Win_API_Wrapper (...) is
   Dummy : BOOL := Some_Win_API (...);
begin
   null;
end Some_Win_API_Wrapper;

> (Some other
> languages are more error prone in this regard.)  But a procedure that
> does a lot of work that happens to be above the "begin" still needs
> "null", which seems sort of silly.

I agree. But I think that the solution is a better balance between effects
and side effects.

I'd like to think of declarations as things done in parallel as opposed to
serialized statements. Unfortunately this is also untrue in Ada.
Serialization is extra coupling, I just feel that something must be wrong
with that (like that "and" vs. "and then" debate, no good arguments for
"and", but still...)

>> I also dislike unnecessary indentations, but what if exception handling is
>> needed? Then you have to create blocks anyway.
> 
> I would prefer a separate try/catch-like statement for exception
> handling.

In C++ that only increases nesting as compared to Ada.

> Exception handling seems totally unrelated to declaring
> things, so I don't see why they should be mixed in the same syntax.

It is rather mixed with scopes, which seems reasonable. Especially, if we
consider exceptions as a part of the contract, which IMO is the only right
way.

>>... and also for forcing the compiler to
>> evaluate statically known constraints at compile time and to remove them
>> from all sorts of dopes. So instead of hiding the skeleton in the cupboard
>> I would openly present it to the public! (:-))
> 
> I don't know how a language standard can *force* things like that.

But it forces evaluation of static constants. We have to allow user-defined
operations there. The type developer should be able to specify whether the
discriminant (constraint) is embedded in each value or not. Then there
should be a mechanism of constraint propagation like in:

type (Size : Positive) is array (...) of Object (Size);

>> I see. But that will require definition of which parts of which statements
>> may act as scopes: loop, if alternative, case choice, exception choice
>> (already so in the "X : others"-kludge), select choice etc. How many pages
>> of ARM? (:-))
> 
> A small fraction of one page.  ;-)
> Any statement list should act as a scope.

That will do the trick! (:-))

>>>>    T := (1, 2, 4, declare X := 9, others => declare Y := 10);
>>>>       -- What would be this? How many Y's could be here?
>>> 
>>> No, I don't propose to allow mixing of decls and expressions!
>>> Just decls and statements.  Decls don't return values.
>> 
>> Once you let them in, then: if I can put declarations among statements, why
>> cannot I put statements among declarations?
>                                 ^^^^^^^^^^^^
> You mean expressions?  You can't put statements (or declarations) among
> expressions because the type is wrong -- a statement does not return a
> value of the right type (it doesn't return a value at all, or in C
> terminology, it returns "void".)

Parameterless functions do something out of nothing (:-)). But in the first
place I meant declarations. Isn't it equivalent: if declarations and
statements can be mixed then it is commutative and there is no more any
distinction between them. So the following should be legal:

package Funny is
   for I in 1..100 loop
      ...
   end loop;
end Foo;

package body Foo is
   X : Integer := 10;
end Foo;

BTW, it seems that there is a parallel to if-elsif-elsif-else. What about
something in this spirit:

declare ... begin
   <statements>
then declare ... begin -- Better keywords needed
   <statements>
then declare ... begin
   <statements>
then declare ... begin
   <statements>
end;

It looks more structured than floating declarations. One could allow it in
all lists of statements.

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



  reply	other threads:[~2005-03-21 18:16 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-03-07 16:23 advice on package design spambox
2005-03-07 21:08 ` Dmitry A. Kazakov
2005-03-08 12:48   ` spambox
2005-03-08 17:18     ` Dmitry A. Kazakov
2005-03-12 19:57   ` Robert A Duff
2005-03-12 20:45     ` Dmitry A. Kazakov
2005-03-12 21:59       ` Robert A Duff
2005-03-13  9:23         ` Dmitry A. Kazakov
2005-03-16 20:41           ` Robert A Duff
2005-03-17 10:22             ` Dmitry A. Kazakov
2005-03-17 14:04               ` Robert A Duff
2005-03-17 15:59                 ` Dmitry A. Kazakov
2005-03-17 19:10                   ` Robert A Duff
2005-03-17 19:47                     ` Martin Dowie
2005-03-17 20:55                       ` Robert A Duff
2005-03-17 21:14                         ` Marius Amado Alves
2005-03-18  9:31                           ` Martin Dowie
2005-03-18  9:38                         ` Martin Dowie
2005-03-21 16:19                           ` Robert A Duff
2005-03-17 20:48                     ` Dmitry A. Kazakov
2005-03-17 21:26                       ` Robert A Duff
2005-03-18  3:06                         ` Jared
2005-03-18 10:00                         ` Dmitry A. Kazakov
2005-03-21 16:17                           ` Robert A Duff
2005-03-21 18:16                             ` Dmitry A. Kazakov [this message]
2005-03-21 20:35                               ` Robert A Duff
2005-03-22 10:55                                 ` Dmitry A. Kazakov
2005-03-17 23:23                 ` Randy Brukardt
replies disabled

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