comp.lang.ada
 help / color / mirror / Atom feed
* Reprise: 'in out' parameters for functions
@ 2004-04-07 20:31 Stephen Leake
  2004-04-08 18:42 ` Georg Bauhaus
  2004-04-13 14:45 ` Robert I. Eachus
  0 siblings, 2 replies; 90+ messages in thread
From: Stephen Leake @ 2004-04-07 20:31 UTC (permalink / raw)
  To: comp.lang.ada

I just ran across a need for an 'in out' parameter in a function, in
"real code", so I thought I post it here "just for fun" :).

This is what I wanted to declare:

function Parse
  (Error_Label : in     String;
   Token       : in out Token_List.List_Iterator)
  return String;
  --  Process Token, which should contain '([Config_File =>] <string>)'.
  --  Return the string.
  --  Delete parsed tokens from Token.

Token must be 'in out', because the next parse function called wants
to work on the stuff after the config file.

Parse must be a function, because I'm returning a String.

The work-around is to use a procedure and a bounded string:

   procedure Parse
     (Error_Label      : in     String;
      Token            : in out Token_List.List_Iterator;
      Config_File_Name :    out OpenToken.Buffers.Bounded_String);

In this instance, the body of Parse deals with
OpenToken.Buffers.Bounded_String anyway, so there's no actual new
overhead introduced. But the user interface is not as clean as it
could be.

-- 
-- Stephe




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

* Re: Reprise: 'in out' parameters for functions
       [not found] <u8yh75y33.fsf@acm.org>
@ 2004-04-07 23:54 ` Alexander E. Kopilovich
       [not found] ` <WLZI9T09aE@VB1162.spb.edu>
  1 sibling, 0 replies; 90+ messages in thread
From: Alexander E. Kopilovich @ 2004-04-07 23:54 UTC (permalink / raw)
  To: comp.lang.ada

Stephen Leake wrote:

> I just ran across a need for an 'in out' parameter in a function, in
> "real code", so I thought I post it here "just for fun" :).
>
> This is what I wanted to declare:
>
> function Parse
>   (Error_Label : in     String;
>    Token       : in out Token_List.List_Iterator)
>   return String;
>   --  Process Token, which should contain '([Config_File =>] <string>)'.
>   --  Return the string.
>   --  Delete parsed tokens from Token.
>
> Token must be 'in out', because the next parse function called wants
> to work on the stuff after the config file.
>
> Parse must be a function, because I'm returning a String.
>
> The work-around is to use a procedure and a bounded string:
>
>    procedure Parse
>      (Error_Label      : in     String;
>       Token            : in out Token_List.List_Iterator;
>       Config_File_Name :    out OpenToken.Buffers.Bounded_String);
>
> In this instance, the body of Parse deals with
> OpenToken.Buffers.Bounded_String anyway, so there's no actual new
> overhead introduced. But the user interface is not as clean as it
> could be.

One thing is missing in this your explanation: why exactly you don't want to
make that List_Iterator global (instead of passing it as IN OUT argument) ?



Alexander Kopilovitch                      aek@vib.usr.pu.ru
Saint-Petersburg
Russia




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

* Re: Reprise: 'in out' parameters for functions
       [not found] ` <WLZI9T09aE@VB1162.spb.edu>
@ 2004-04-08  2:21   ` Stephen Leake
  0 siblings, 0 replies; 90+ messages in thread
From: Stephen Leake @ 2004-04-08  2:21 UTC (permalink / raw)
  To: comp.lang.ada

"Alexander E. Kopilovich" <aek@VB1162.spb.edu> writes:

> Stephen Leake wrote:
> 
> > This is what I wanted to declare:
> >
> > function Parse
> >   (Error_Label : in     String;
> >    Token       : in out Token_List.List_Iterator)
> >   return String;
> >   --  Process Token, which should contain '([Config_File =>] <string>)'.
> >   --  Return the string.
> >   --  Delete parsed tokens from Token.
> >
> One thing is missing in this your explanation: why exactly you don't want to
> make that List_Iterator global (instead of passing it as IN OUT argument) ?

Hmm. I suppose that is a legitimate question. 

My answer is "I never make anything global unless it has to be,
because that usually leads to trouble".

In this case, Token is actually the contents of an aggregate, part of
a larger statement that is dynamically allocated. It must be modified
in place; copying it to a global to pass it to this routine would be a
maintenance nightmare.

And no, I don't consider "Ada doesn't allow 'in out' in functions" a
good reason to make something global; I'll change it to a procedure
first.

-- 
-- Stephe




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

* Re: Reprise: 'in out' parameters for functions
       [not found] <u4qrv5hwr.fsf@acm.org>
@ 2004-04-08 17:19 ` Alexander E. Kopilovich
       [not found] ` <bRecOT0TxF@VB1162.spb.edu>
  1 sibling, 0 replies; 90+ messages in thread
From: Alexander E. Kopilovich @ 2004-04-08 17:19 UTC (permalink / raw)
  To: comp.lang.ada

Stephen Leake wrote:

> > > This is what I wanted to declare:
> > >
> > > function Parse
> > >   (Error_Label : in     String;
> > >    Token       : in out Token_List.List_Iterator)
> > >   return String;
> > >   --  Process Token, which should contain '([Config_File =>] <string>)'.
> > >   --  Return the string.
> > >   --  Delete parsed tokens from Token.
> > >
> > One thing is missing in this your explanation: why exactly you don't want to
> > make that List_Iterator global (instead of passing it as IN OUT argument) ?

> My answer is "I never make anything global unless it has to be,
> because that usually leads to trouble".

Yes, but this is general attitude, and it says nothing definite about
particular case - it can be that detailed analysis of this particular case
will show reasons to make it global.

> In this case, Token is actually the contents of an aggregate, part of
> a larger statement that is dynamically allocated. It must be modified
> in place; copying it to a global to pass it to this routine would be a
> maintenance nightmare.

I did not think about copying. I think that real question may be whether
Parse conceptually deals with Token_List.List_Iterator or with the whole
List_Iterator. In the latter case a global is generally possible without any
copying.

> And no, I don't consider "Ada doesn't allow 'in out' in functions" a
> good reason to make something global; I'll change it to a procedure
> first.

Certainly. But there may be other reasons (originated from detailed design).



Alexander Kopilovich                      aek@vib.usr.pu.ru
Saint-Petersburg
Russia





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

* Re: Reprise: 'in out' parameters for functions
  2004-04-07 20:31 Stephen Leake
@ 2004-04-08 18:42 ` Georg Bauhaus
  2004-04-08 20:32   ` Randy Brukardt
  2004-04-08 23:48   ` Stephen Leake
  2004-04-13 14:45 ` Robert I. Eachus
  1 sibling, 2 replies; 90+ messages in thread
From: Georg Bauhaus @ 2004-04-08 18:42 UTC (permalink / raw)


Stephen Leake <stephen_leake@acm.org> wrote:
 
:   Token       : in out Token_List.List_Iterator)
Is
    Token       : access Token_List.List_Iterator)
not an option?




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-08 18:42 ` Georg Bauhaus
@ 2004-04-08 20:32   ` Randy Brukardt
  2005-01-12 15:15     ` okellogg
  2004-04-08 23:48   ` Stephen Leake
  1 sibling, 1 reply; 90+ messages in thread
From: Randy Brukardt @ 2004-04-08 20:32 UTC (permalink / raw)


"Georg Bauhaus" <sb463ba@l1-hrz.uni-duisburg.de> wrote in message
news:c546fd$lkb$3@a1-hrz.uni-duisburg.de...
> Stephen Leake <stephen_leake@acm.org> wrote:
>
> :   Token       : in out Token_List.List_Iterator)
> Is
>     Token       : access Token_List.List_Iterator)
> not an option?

It's rarely an option, because it (a) forces a particular declaration
('aliased') on users that have no need to know and (b) makes a messy call
with the need to use '[Unchecked_]Access in every call.

I prefer to simply make the List_Iterator a type that internally contains
indirection. (That usually requires it to be a controlled type). Then the
actual data can be manipulated.

But whether that solution is worth the extra work depends on how much the
interface is going to be used. (It isn't worth the effort for a rarely used
interface.)

                 Randy.






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

* Re: Reprise: 'in out' parameters for functions
       [not found] ` <bRecOT0TxF@VB1162.spb.edu>
@ 2004-04-08 23:46   ` Stephen Leake
  2004-04-09  9:23     ` Florian Weimer
  2004-04-09 13:12     ` Wojtek Narczynski
  0 siblings, 2 replies; 90+ messages in thread
From: Stephen Leake @ 2004-04-08 23:46 UTC (permalink / raw)
  To: comp.lang.ada

"Alexander E. Kopilovich" <aek@VB1162.spb.edu> writes:

> Stephen Leake wrote:
> 
> > > > This is what I wanted to declare:
> > > >
> > > > function Parse
> > > >   (Error_Label : in     String;
> > > >    Token       : in out Token_List.List_Iterator)
> > > >   return String;
> > > >   --  Process Token, which should contain '([Config_File =>] <string>)'.
> > > >   --  Return the string.
> > > >   --  Delete parsed tokens from Token.
> > > >
> > > One thing is missing in this your explanation: why exactly you don't want to
> > > make that List_Iterator global (instead of passing it as IN OUT argument) ?
> > In this case, Token is actually the contents of an aggregate, part of
> > a larger statement that is dynamically allocated. It must be modified
> > in place; copying it to a global to pass it to this routine would be a
> > maintenance nightmare.
> 
> I did not think about copying. I think that real question may be whether
> Parse conceptually deals with Token_List.List_Iterator or with the whole
> List_Iterator. In the latter case a global is generally possible without any
> copying.

Yes, there are times when globals are appropriate. No, this is not one
of those times. You'll just have to take my word for it.

Ada has a wart. Let's admit it, and move on.
-- 
-- Stephe




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-08 18:42 ` Georg Bauhaus
  2004-04-08 20:32   ` Randy Brukardt
@ 2004-04-08 23:48   ` Stephen Leake
  1 sibling, 0 replies; 90+ messages in thread
From: Stephen Leake @ 2004-04-08 23:48 UTC (permalink / raw)
  To: comp.lang.ada

Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> writes:

> Stephen Leake <stephen_leake@acm.org> wrote:
>  
> :   Token       : in out Token_List.List_Iterator)
> Is
>     Token       : access Token_List.List_Iterator)
> not an option?

Good point. I had not actually considered that. In general, access
types are as much a pain (in different ways) than globals.

List_Iterator itself is a private access type, so it's not much of a
stretch here.

-- 
-- Stephe




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-08 23:46   ` Stephen Leake
@ 2004-04-09  9:23     ` Florian Weimer
  2004-04-09 10:04       ` Dmitry A. Kazakov
                         ` (2 more replies)
  2004-04-09 13:12     ` Wojtek Narczynski
  1 sibling, 3 replies; 90+ messages in thread
From: Florian Weimer @ 2004-04-09  9:23 UTC (permalink / raw)


Stephen Leake <stephen_leake@acm.org> writes:

> Ada has a wart. Let's admit it, and move on.

Can't we fix that one without breaking backwards compatibility?  Or
are politics involved?

-- 
Current mail filters: many dial-up/DSL/cable modem hosts, and the
following domains: postino.it, tiscali.co.uk, tiscali.cz, tiscali.it,
voila.fr.



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09  9:23     ` Florian Weimer
@ 2004-04-09 10:04       ` Dmitry A. Kazakov
  2004-04-09 11:23         ` Martin Krischik
  2004-04-09 22:47         ` Florian Weimer
  2004-04-09 11:27       ` Stephen Leake
  2004-04-09 22:46       ` Randy Brukardt
  2 siblings, 2 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-09 10:04 UTC (permalink / raw)


Florian Weimer wrote:

> Stephen Leake <stephen_leake@acm.org> writes:
> 
>> Ada has a wart. Let's admit it, and move on.
> 
> Can't we fix that one without breaking backwards compatibility?

procedure Has_A_Result (...) return Result;

> Or are politics involved?

I think so. But there also is the problem of evaluation order, though simply
ignored for access parameters of functions.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 10:04       ` Dmitry A. Kazakov
@ 2004-04-09 11:23         ` Martin Krischik
  2004-04-09 12:44           ` Dmitry A. Kazakov
  2004-04-09 22:47         ` Florian Weimer
  1 sibling, 1 reply; 90+ messages in thread
From: Martin Krischik @ 2004-04-09 11:23 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> Florian Weimer wrote:
> 
>> Stephen Leake <stephen_leake@acm.org> writes:
>> 
>>> Ada has a wart. Let's admit it, and move on.
>> 
>> Can't we fix that one without breaking backwards compatibility?
> 
> procedure Has_A_Result (...) return Result;

This solution would call for precise documentation (advantages,
disadvantages) etc. pp. Plus a quick summary ("functions are faster") for
the beginner.

Otherwise the same problems as with "access all" will arise. Many programers
use "access all" all the time - even when not needed, ignoring the
diadvantages.

>> Or are politics involved?
> 
> I think so. But there also is the problem of evaluation order, though
> simply ignored for access parameters of functions.

See above. Have you heard of GNATs "pragma Pure_Function"?

Prehaps making function even more restive plus procedures with return plus a
"functions are faster" statement might do the trick.

With Regards

Martin

-- 
mailto://krischik@users.sourceforge.net
http://www.ada.krischik.com




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09  9:23     ` Florian Weimer
  2004-04-09 10:04       ` Dmitry A. Kazakov
@ 2004-04-09 11:27       ` Stephen Leake
  2004-04-09 22:46       ` Randy Brukardt
  2 siblings, 0 replies; 90+ messages in thread
From: Stephen Leake @ 2004-04-09 11:27 UTC (permalink / raw)
  To: comp.lang.ada

Florian Weimer <fw@deneb.enyo.de> writes:

> Stephen Leake <stephen_leake@acm.org> writes:
> 
> > Ada has a wart. Let's admit it, and move on.
> 
> Can't we fix that one without breaking backwards compatibility?  

We could; simply permit 'in out' in functions.

> Or are politics involved?

Yes. There are some people (members of the ARG included) who don't
want 'in out' in functions.

I have only talked seriously with one person who holds that view (Rod
Chapman, at the last SigAda). I can't really do justice to his view
here, so I won't try, but it was based on serious considerations. I
had the impression that if I spent enough time, I could convince him
to change. On the other hand, he may have had the same impression
about me :).

As Robert Dewar says, there are no new arguments here, so there is no
reason to reopen the discussion. I was just venting :).

-- 
-- Stephe




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 11:23         ` Martin Krischik
@ 2004-04-09 12:44           ` Dmitry A. Kazakov
  2004-04-09 22:48             ` Randy Brukardt
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-09 12:44 UTC (permalink / raw)


Martin Krischik wrote:

> Dmitry A. Kazakov wrote:
> 
>> Florian Weimer wrote:
>> 
>>> Stephen Leake <stephen_leake@acm.org> writes:
>>> 
>>>> Ada has a wart. Let's admit it, and move on.
>>> 
>>> Can't we fix that one without breaking backwards compatibility?
>> 
>> procedure Has_A_Result (...) return Result;
> 
> This solution would call for precise documentation (advantages,
> disadvantages) etc. pp. Plus a quick summary ("functions are faster") for
> the beginner.
>
> Otherwise the same problems as with "access all" will arise. Many
> programers use "access all" all the time - even when not needed, ignoring
> the diadvantages.

This is very true. And there is also a nasty problem with specific access
types for beginners:
 
   type Root is tagged ...;
   type Handle is access Root'Class;

   type Derived is new Root with ...;
   type Derived_Ptr is access Derived;

function Factory return Handle is
   Ptr : Derived_Ptr := new Derived;
begin
   Prepare (Ptr.all);
   return Handle (Ptr); -- Error!
end Factory;

Should cast:

function Factory return Handle is
   Ptr : Handle := new Derived;
begin
   Prepare (Derived (Ptr.all));
   return Ptr;
end Factory;

>>> Or are politics involved?
>> 
>> I think so. But there also is the problem of evaluation order, though
>> simply ignored for access parameters of functions.
> 
> See above. Have you heard of GNATs "pragma Pure_Function"?

Yes, it is a very good thing. I'd like to see it in the standard and
moreover not as a pragma, but as a part of the syntax (in the contract). It
could be very useful, for example, to declare an abstract function as pure,
to force any implementation to conform. Even more useful would be to allow
pure functions in static expressions. The compiler could get an advantage
from knowing that a function is pure:

while Match (Pattern ("..."), Standard_Input) loop
   ... -- Pattern is pure, so the result is a constant
end loop; 

> Prehaps making function even more restive plus procedures with return plus
> a "functions are faster" statement might do the trick.

I think that one should also either 1) fix evaluation order for non-pure
functions and procedures with results or, better, but backward
incompatible, 2) disallow them where the order is not fixed.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-08 23:46   ` Stephen Leake
  2004-04-09  9:23     ` Florian Weimer
@ 2004-04-09 13:12     ` Wojtek Narczynski
  2004-04-09 15:48       ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen
                         ` (2 more replies)
  1 sibling, 3 replies; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-09 13:12 UTC (permalink / raw)


Hello,

> Ada has a wart. Let's admit it, and move on.

Several warts. For example, abstraction inversion (just look at ACT
PolyOrb code, or try to implement tree crabbing), type system unable
to express physical units, very limited standard library (compare it
to say CM3 Modula, or Java). But the problem real problem IMO is that
the development of the language has stagnated.

Regards,
Wojtek



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

* Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-09 13:12     ` Wojtek Narczynski
@ 2004-04-09 15:48       ` Jacob Sparre Andersen
  2004-04-10 13:07         ` Wojtek Narczynski
  2004-04-09 16:17       ` Reprise: 'in out' parameters for functions Georg Bauhaus
  2004-04-09 17:09       ` Pascal Obry
  2 siblings, 1 reply; 90+ messages in thread
From: Jacob Sparre Andersen @ 2004-04-09 15:48 UTC (permalink / raw)


Wojtek Narczynski wrote:

> Several warts. For example, [...] type system unable to express
> physical units, [...].

The type system is not _unable_ to express physical units.  It just
has some limitations in how you can do it.  And although I am annoyed
by the limitations, I still haven't seen a description of how the
language can make it easier, without introducing problems outweighing
the benefits [1].

> But the problem real problem IMO is that the development of the
> language has stagnated.

What to one programmer appears as stagnation, appears as stability to
another programmer.  IMO change is grossly overrated.

It is fine to use GNAT to do experiments with possible changes to Ada.
And it is also fine to merge the experiments with sensible results
into the standard, but I don't want to have to reread the LRM every
six month.

In general, change means cost (learning and tools).  If the cost isn't
exceeded by the benefits, then the change is bad.

Jacob

[1] I have tried to formulate such a modification to Ada myself, but
    ended up with something that appeared to be (provably) impossible
    to compile.
-- 
"Computer Science is to Science, as Plumbing is to Hydrodynamics"



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 13:12     ` Wojtek Narczynski
  2004-04-09 15:48       ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen
@ 2004-04-09 16:17       ` Georg Bauhaus
  2004-04-10  2:28         ` Wojtek Narczynski
  2004-04-09 17:09       ` Pascal Obry
  2 siblings, 1 reply; 90+ messages in thread
From: Georg Bauhaus @ 2004-04-09 16:17 UTC (permalink / raw)


Wojtek Narczynski <wojtek@power.com.pl> wrote:
: Several warts. For example, abstraction inversion (just look at ACT
: PolyOrb code, or try to implement tree crabbing),

I take it Ada forces abstraction in version in cases?
Could you name an example unit to look at?

: type system unable
: to express physical units,

Still, you might have

   type Quantity is abstract tagged private;

   function in_meters (x: Quantity) return Units.meter;
   function in_yards (x: Quantity) return Units.yard;
   --  etc...

: But the problem real problem IMO is that
: the development of the language has stagnated.

What's missing?




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 13:12     ` Wojtek Narczynski
  2004-04-09 15:48       ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen
  2004-04-09 16:17       ` Reprise: 'in out' parameters for functions Georg Bauhaus
@ 2004-04-09 17:09       ` Pascal Obry
  2004-04-10  2:37         ` Wojtek Narczynski
  2 siblings, 1 reply; 90+ messages in thread
From: Pascal Obry @ 2004-04-09 17:09 UTC (permalink / raw)



wojtek@power.com.pl (Wojtek Narczynski) writes:

> to say CM3 Modula, or Java). But the problem real problem IMO is that
> the development of the language has stagnated.

This seems just strange to me! Latest Ada standard has moved forward a lot and
all this is many aspects of the language. And Ada0Y is another step (admitedly
smaller one) in this direction!

Or maybe you are just trolling :)

Pascal.

-- 

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



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09  9:23     ` Florian Weimer
  2004-04-09 10:04       ` Dmitry A. Kazakov
  2004-04-09 11:27       ` Stephen Leake
@ 2004-04-09 22:46       ` Randy Brukardt
  2 siblings, 0 replies; 90+ messages in thread
From: Randy Brukardt @ 2004-04-09 22:46 UTC (permalink / raw)


"Florian Weimer" <fw@deneb.enyo.de> wrote in message
news:87brm1pksa.fsf@deneb.enyo.de...
> Stephen Leake <stephen_leake@acm.org> writes:
>
> > Ada has a wart. Let's admit it, and move on.
>
> Can't we fix that one without breaking backwards compatibility?  Or
> are politics involved?

Sure. But there is no will. So it won't be fixed. (See AI-323, voted "No
Action").

             Randy.






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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 10:04       ` Dmitry A. Kazakov
  2004-04-09 11:23         ` Martin Krischik
@ 2004-04-09 22:47         ` Florian Weimer
  2004-04-10 10:49           ` Dmitry A. Kazakov
  1 sibling, 1 reply; 90+ messages in thread
From: Florian Weimer @ 2004-04-09 22:47 UTC (permalink / raw)


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

> > Can't we fix that one without breaking backwards compatibility?
> 
> procedure Has_A_Result (...) return Result;

Well, this is solution is obviously quite bad because "procedure" and
"function" are now almost (but not quite) interchangeable.

> > Or are politics involved?
> 
> I think so. But there also is the problem of evaluation order,
> though simply ignored for access parameters of functions.

Does making parameters "in out" really make things considerably worse?

-- 
Current mail filters: many dial-up/DSL/cable modem hosts, and the
following domains: postino.it, tiscali.co.uk, tiscali.cz, tiscali.it,
voila.fr.



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 12:44           ` Dmitry A. Kazakov
@ 2004-04-09 22:48             ` Randy Brukardt
  2004-04-14 14:40               ` Robert I. Eachus
  0 siblings, 1 reply; 90+ messages in thread
From: Randy Brukardt @ 2004-04-09 22:48 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:c565si$2qlp6q$1@ID-77047.news.uni-berlin.de...
> Martin Krischik wrote:
> > See above. Have you heard of GNATs "pragma Pure_Function"?
>
> Yes, it is a very good thing. I'd like to see it in the standard and
> moreover not as a pragma, but as a part of the syntax (in the contract).
It
> could be very useful, for example, to declare an abstract function as
pure,
> to force any implementation to conform. Even more useful would be to allow
> pure functions in static expressions. The compiler could get an advantage
> from knowing that a function is pure:

I agree with all of this too. Also not going to happen. See AI-290, also
voted "No Action".

               Randy.






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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 16:17       ` Reprise: 'in out' parameters for functions Georg Bauhaus
@ 2004-04-10  2:28         ` Wojtek Narczynski
  2004-04-10  9:46           ` Georg Bauhaus
                             ` (3 more replies)
  0 siblings, 4 replies; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-10  2:28 UTC (permalink / raw)


Hello,

> I take it Ada forces abstraction in version in cases?
> Could you name an example unit to look at?

'Inversion' not 'in version' incase it were more than a typo. When you
implement a semaphore over a protected object, or in general when you
need to lock / unlock by yourself. Classic example:

polyorb-tasking-profiles-full_tasking-mutexes.adb

Or try to implement tree crabbing. Hell, try to implement a list
updateable concurrently from multiple tasks. You _will_ end up
implementing a semaphore over a protected, over a semaphore.

Or the simplest possible: two protected counters, try to get the sum
atomically.

> : type system unable
> : to express physical units,
> 
> Still, you might have
> 
>    type Quantity is abstract tagged private;
> 
>    function in_meters (x: Quantity) return Units.meter;
>    function in_yards (x: Quantity) return Units.yard;
>    --  etc...

Sure, let us continue:

function in_kilograms (x: Quantity) return Units.yard;
-- Blows at runtime

This just cannot be done right in Ada.

> : But the problem real problem IMO is that
> : the development of the language has stagnated.
> 
> What's missing?

From the language? For example parameters for exceptions.

Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 17:09       ` Pascal Obry
@ 2004-04-10  2:37         ` Wojtek Narczynski
  0 siblings, 0 replies; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-10  2:37 UTC (permalink / raw)


Hello,

> Or maybe you are just trolling :)

Indeed I might have been, but only a litte.

Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10  2:28         ` Wojtek Narczynski
@ 2004-04-10  9:46           ` Georg Bauhaus
  2004-04-10 10:49           ` Dmitry A. Kazakov
                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 90+ messages in thread
From: Georg Bauhaus @ 2004-04-10  9:46 UTC (permalink / raw)


Wojtek Narczynski <wojtek@power.com.pl> wrote:
: Hello,
: 
:> I take it Ada forces abstraction in version in cases?
:> Could you name an example unit to look at?
: 
: 'Inversion' not 'in version' incase it were more than a typo.

A typo, sorry.

: When you
: implement a semaphore over a protected object, or in general when you
: need to lock / unlock by yourself. Classic example:
: 
: polyorb-tasking-profiles-full_tasking-mutexes.adb

Thanks. Given that mutex and semaphores have been known
when Ada was made, I wonder whether there aren't some
external forces at work which lead to the requirement
of using tasking constructs below language level.
Not Ada's fault from this perspective.

Incidentally, there is some abstraction inversion criticism
quoting Ada, mutex, and tasks. But has not been brought up
to date where date refers to 1995. So there is another
meaning of "classic".

 
: function in_kilograms (x: Quantity) return Units.yard;
: -- Blows at runtime

I don't think so. How do you write an expression expecting
Unis.kilogram, where the compiler sees a function returning
Units.yard, such that the compiler does not reject?

: This just cannot be done right in Ada.


:> What's missing?
: 
: From the language? For example parameters for exceptions.

Not a good idea I think, though practical for use in quick and
dirty fixes of design errors. Programm logic can be programmed.




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10  2:28         ` Wojtek Narczynski
  2004-04-10  9:46           ` Georg Bauhaus
@ 2004-04-10 10:49           ` Dmitry A. Kazakov
  2004-04-10 15:35             ` Wojtek Narczynski
  2004-04-14 15:57             ` Robert I. Eachus
  2004-04-10 12:32           ` Wojtek Narczynski
  2004-04-14 15:46           ` Robert I. Eachus
  3 siblings, 2 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-10 10:49 UTC (permalink / raw)


Wojtek Narczynski wrote:

>> I take it Ada forces abstraction in version in cases?
>> Could you name an example unit to look at?
> 
> 'Inversion' not 'in version' incase it were more than a typo. When you
> implement a semaphore over a protected object, or in general when you
> need to lock / unlock by yourself. Classic example:
> 
> polyorb-tasking-profiles-full_tasking-mutexes.adb
> 
> Or try to implement tree crabbing. Hell, try to implement a list
> updateable concurrently from multiple tasks. You _will_ end up
> implementing a semaphore over a protected, over a semaphore.
> 
> Or the simplest possible: two protected counters, try to get the sum
> atomically.

This has nothing to do with abstraction inversion. The problem here is that
Ada does not have multiple protected actions. Same problem with tasks,
there cannot be rendezvous with multiple tasks. It is much work to solve
that. Especially to convince people that prefix notation is inherently bad.

>> : type system unable
>> : to express physical units,
>> 
>> Still, you might have
>> 
>>    type Quantity is abstract tagged private;
>> 
>>    function in_meters (x: Quantity) return Units.meter;
>>    function in_yards (x: Quantity) return Units.yard;
>>    --  etc...
> 
> Sure, let us continue:
> 
> function in_kilograms (x: Quantity) return Units.yard;
> -- Blows at runtime
> 
> This just cannot be done right in Ada.

This is wrong:

http://home.t-online.de/home/Christ-Usch.Grein/Ada/Dimension.html

The type system is capable to express dimensioned units. The major problem
here is not the type system, but inability to get rid of statically known
discriminants, which makes an implementation inefficient.

>> : But the problem real problem IMO is that
>> : the development of the language has stagnated.
>> 
>> What's missing?
> 
> From the language? For example parameters for exceptions.

How they could have parameters? There are only two ways for dealing with
exceptions. Either 1) all of them are of one [specific] type (maybe an
implicit one) or 2) they are of different types (maybe rooted in the same
root type [class-wide approach]). Ada has 1), which excludes parameters. If
you think that 2) would be better for Ada then solve the following:

generic
package Crazy is
   type Virtual is new Exception with ...;
      -- Note that Virtual exists in an instance of Crazy only.
      -- It is finalized together with the instance.
   procedure Show_Me (Object : Virtual);
end Crazy;

package body Crazy is
   Local : Integer := 0;

   procedure Show_Me (Object : Virtual) is
   begin
      Put_Line (Integer'Image (Local));
   end Show_Me;
begin
   raise Virtual (your fine parameters);
end Crazy;

declare
   package Catch_It is new Crazy;
begin
   null;
exception
   when Error : others =>
      -- What sort of type has Error?
      -- Can I dispatch to Show_Me?
      -- What it will print?

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 22:47         ` Florian Weimer
@ 2004-04-10 10:49           ` Dmitry A. Kazakov
  2004-04-10 11:11             ` Florian Weimer
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-10 10:49 UTC (permalink / raw)


Florian Weimer wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> > Can't we fix that one without breaking backwards compatibility?
>> 
>> procedure Has_A_Result (...) return Result;
> 
> Well, this is solution is obviously quite bad because "procedure" and
> "function" are now almost (but not quite) interchangeable.

Isn't an access parameter almost interchangeable with an "in out" parameter?
The word "procedure" tells that there are many results. "Return" tells that
among them there is one dedicated.

>> > Or are politics involved?
>> 
>> I think so. But there also is the problem of evaluation order,
>> though simply ignored for access parameters of functions.
> 
> Does making parameters "in out" really make things considerably worse?

Let me use your argument: what would be the difference between "function"
and "procedure" then?

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10 10:49           ` Dmitry A. Kazakov
@ 2004-04-10 11:11             ` Florian Weimer
  2004-04-10 13:26               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 90+ messages in thread
From: Florian Weimer @ 2004-04-10 11:11 UTC (permalink / raw)


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


> > Well, this is solution is obviously quite bad because "procedure" and
> > "function" are now almost (but not quite) interchangeable.
> 
> Isn't an access parameter almost interchangeable with an "in out"
> parameter?

No, it isn't.  You can't obtain an access value for most objects.

> Let me use your argument: what would be the difference between "function"
> and "procedure" then?

Its use.  A procedure call is a statement, a function call is a name
(and thus part of an expression).

-- 
Current mail filters: many dial-up/DSL/cable modem hosts, and the
following domains: postino.it, tiscali.co.uk, tiscali.cz, tiscali.it,
voila.fr.



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10  2:28         ` Wojtek Narczynski
  2004-04-10  9:46           ` Georg Bauhaus
  2004-04-10 10:49           ` Dmitry A. Kazakov
@ 2004-04-10 12:32           ` Wojtek Narczynski
  2004-04-14 15:46           ` Robert I. Eachus
  3 siblings, 0 replies; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-10 12:32 UTC (permalink / raw)


> function in_kilograms (x: Quantity) return Units.yard;
> -- Blows at runtime

Oops :-)

"The morning is wiser than the evening."

Regards,
Wojtek



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-09 15:48       ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen
@ 2004-04-10 13:07         ` Wojtek Narczynski
  2004-04-10 13:52           ` Jacob Sparre Andersen
  0 siblings, 1 reply; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-10 13:07 UTC (permalink / raw)


Jacob,

> The type system is not _unable_ to express physical units.  It just
> has some limitations in how you can do it.

It depends on how exactly you phrase out the task. If you define it as
having a static check on physical units, I believe Ada type system is
not able to do this. You are left with paper and pencil.

> And although I am annoyed by the limitations, I still haven't seen
> a description of how the  language can make it easier, without introducing
> problems outweighing the benefits. I have tried to formulate such
> a modification to Ada myself, but ended up with something that appeared 
> to be (provably) impossible to compile.

(I converged your note here)

I find this subject fascinating. I remember matchcad doing units check
for me 10 years ago when I was in secondary school, yet I have not
seen any compiler capable of doing the same. I was thinking that a
term rewriting system for partial evaluation of the program would do
the job. Or maybe are there problems with modularization? Could you
point me at your results, if they are public?

>> But the problem real problem IMO is that the development of the
>> language has stagnated.
> 
> What to one programmer appears as stagnation, appears as stability
> to another programmer. 

Point taken.

> It is fine to use GNAT to do experiments with possible changes to
> Ada.

I was trying, but it turned out that I am not smart enough. The
codebase is just too large for me to comprehend. For example the
(in)famous 'in out' for functions. I really have no idea where to look
at in those megabytes. I had hoped that maybe GPS as a code
comprehension aid, would help, but GNAT seems to be too large for GPS,
which I find a bit ironic.

Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10 11:11             ` Florian Weimer
@ 2004-04-10 13:26               ` Dmitry A. Kazakov
  2004-04-10 20:50                 ` Georg Bauhaus
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-10 13:26 UTC (permalink / raw)


Florian Weimer wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> > Well, this is solution is obviously quite bad because "procedure" and
>> > "function" are now almost (but not quite) interchangeable.
>> 
>> Isn't an access parameter almost interchangeable with an "in out"
>> parameter?
> 
> No, it isn't.  You can't obtain an access value for most objects.

So what? The only reasonable use of an access parameter is to have "in out"
where it is not allowed. [I do not count circumventing by-copy parameter
passing for reasonable]

>> Let me use your argument: what would be the difference between "function"
>> and "procedure" then?
> 
> Its use.  A procedure call is a statement, a function call is a name
> (and thus part of an expression).

Expression is a part of a statement, so I see as much difference as between
+ and "+".

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-10 13:07         ` Wojtek Narczynski
@ 2004-04-10 13:52           ` Jacob Sparre Andersen
  2004-04-11  2:45             ` Hyman Rosen
  2004-04-13  9:53             ` Wojtek Narczynski
  0 siblings, 2 replies; 90+ messages in thread
From: Jacob Sparre Andersen @ 2004-04-10 13:52 UTC (permalink / raw)


Wojtek Narczynski wrote:
> Jacob Sparre Andersen wrote:

> > The type system is not _unable_ to express physical units.  It
> > just has some limitations in how you can do it.
> 
> It depends on how exactly you phrase out the task. If you define it
> as having a static check on physical units, I believe Ada type
> system is not able to do this. You are left with paper and pencil.

One of my programs disagrees somewhat with your statement.  I switched
from run-time to compile-time checking of unit mismatches, when a
recent version of Macks made it practical to start using compile-time
checks.

It is though correct that physical units are not a specific Ada type,
but rather have to be implemented using the basic type system.  With a
tool like Macks, it is reasonably fast to implement the necessary
types for compile-time checking of unit mismatch.  Before Macks
matured sufficiently, I either used run-time checks or hand-coded the
types I needed.

> > And although I am annoyed by the limitations, I still haven't seen
> > a description of how the language can make it easier, without
> > introducing problems outweighing the benefits. I have tried to
> > formulate such a modification to Ada myself, but ended up with
> > something that appeared to be (provably) impossible to compile.
> 
> (I converged your note here)
> 
> I find this subject fascinating. I remember matchcad doing units
> check for me 10 years ago when I was in secondary school, yet I have
> not seen any compiler capable of doing the same. I was thinking that
> a term rewriting system for partial evaluation of the program would
> do the job. Or maybe are there problems with modularization? Could
> you point me at your results, if they are public?

They are unfortunately not published (and they are written in Danish).
Also, I stopped once _I_ was certain it couldn't be done, so I never
wrote down a complete proof, but just enough to convince a colleague.
It should be noted that my analysis was tied rather strongly to Ada,
and a more relaxed programming language might be able to do something
that would be sufficiently close to full compile-time unit checking.

Are you sure that "matchcad" actually did full compile-time unit
checking?

Jacob
-- 
�USA fights for the right of the individual.�
�Yes.  Those of the individual George W. Bush.�
                                     -- with thanks to Olfax



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10 10:49           ` Dmitry A. Kazakov
@ 2004-04-10 15:35             ` Wojtek Narczynski
  2004-04-10 21:01               ` Georg Bauhaus
                                 ` (2 more replies)
  2004-04-14 15:57             ` Robert I. Eachus
  1 sibling, 3 replies; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-10 15:35 UTC (permalink / raw)


Dimitry,

> This has nothing to do with abstraction inversion. 

Would you please take care to explain to me, what abstraction
inversion is, according to you? For me abstraction inversion is when
you need to build low level primitives from high level primitives
(built on low level primitives), because the high level primitives are
not expressive enough.

> The problem here is that Ada does not have multiple
> protected actions.

Google has not heard of "multiple protected actions", neither have I.
But I think know what you mean, for my own needs I was calling this
"compound protected". It seems to require proper tail recursion to
work.

At least we seem to agree that Ada concurrency features also have
warts.

---

> This is wrong:
> 
> http://home.t-online.de/home/Christ-Usch.Grein/Ada/Dimension.html
> 
> The type system is capable to express dimensioned units.

By "express" I don't mean bent over in an such a way that your
compiler checked your units for you, nor have your compiler mostly
check your units for you, nor write yet another compiler to work on
top of your compiler. I mean have your compiler statically check your
units for you.

I am afraid that this link show exactly that I am, unfortunately,
right. The two compile time solutions are: 1. "Checks in assignments
concerning physical dimensions are not performed.", 2. From what I've
been able to understand Macks has a language, which compiles to Ada.

---

> > From the language? For example parameters for exceptions.
> 
> How they could have parameters? There are only two ways for dealing
> with  exceptions. Either 1) all of them are of one [specific] type
> (maybe an implicit one) or 2) they are of different types (maybe
> rooted in the same root type [class-wide approach]).

You seem to be very well educated in Matematics. Thus you know that
inexistence proofs are among the hardest. Please don't provoke me to
ask you to proove that there are only two ways of dealing with
exceptions.

And once you assume false, you can prove anything.

> Ada has 1), which excludes parameters. If you think that 2) would be
> better for Ada then solve the following:

You assumed that the root type for Exception would be tagged record.
Indeed with this assumption it may be hard to maintain the conceptual
integrity of the language. But I think this level of parametrization
is an overkill. I'd rather use something like "discriminated records
with discriminants only".

Here is a version to start with (which actually compiles and "works"):

generic
package Crazy is
   Bang: exception;
   function T return Boolean;
end Crazy;
 
package body Crazy is
   function T return Boolean is begin return True; end T;
begin
   raise Bang;
end Crazy;

with Crazy;
procedure Sample is
   package Catch_It is new Crazy;
begin
   null;
exception
   when Catch_It.Bang => 
      null;
end Sample;


Here is a parametrized version:

generic
package Crazy is
 
   type Severity_Type is (Hard, Tough, Difficult, Killer, ...);
   type Urgency_Type is (Urgent, Immediate, Now, Asap, ...);
   type Native_Code_Type is new Integer;
 
   exception Bang (Severity : Severity_Type;
      Urgency : Urgency_Type; Native_Code : Native_Code_Type)
 
   function T return Boolean;
 
end Crazy;
 
package body Crazy is
   function T return Boolean is begin return True; end T;
begin
   raise Bang( Hard, Urgent, -1);
end Crazy;

with Crazy;
procedure Sample is
   package Catch_It is new Crazy;
begin
   null;
exception
   when B : Catch_It.Bang =>
      -- Here you'd be are able to access the values,
      -- but not to call anything from the already gone package.
      -- Regarding scope it is not any differnt from the previous
      -- example - we were also accessing Bang in hander.
      Put_Line (B.Severity);
      Put_Line (B.Urgency);
      Put_Line (B.Native_Code);
end Sample;

Please note that this actually works in Modula-3, but you are only
limited to one parameter. Well, all languages have their warts.

GNAT.Sockets is perhaps the best example how the code could benefit
from parametrized exceptions. There you have Socket_Error and that's
it. You need to use compiler specific tricks to extract more info. Or
you can declare a coule dozen of different exceptions. Or a couple
hundred, it depends.

Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10 13:26               ` Dmitry A. Kazakov
@ 2004-04-10 20:50                 ` Georg Bauhaus
  2004-04-11 10:31                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 90+ messages in thread
From: Georg Bauhaus @ 2004-04-10 20:50 UTC (permalink / raw)


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

 
:  The only reasonable use of an access parameter is to have "in out"
: where it is not allowed.

Access parameters go well with access discriminants...?




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10 15:35             ` Wojtek Narczynski
@ 2004-04-10 21:01               ` Georg Bauhaus
  2004-04-10 21:16               ` Georg Bauhaus
  2004-04-11 10:31               ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov
  2 siblings, 0 replies; 90+ messages in thread
From: Georg Bauhaus @ 2004-04-10 21:01 UTC (permalink / raw)


Wojtek Narczynski <wojtek@power.com.pl> wrote:


: I mean have your compiler statically check your
: units for you.

IIRC, Hyman Rosen has demonstrated, a few month ago, how
this can be done with C++ templates.




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10 15:35             ` Wojtek Narczynski
  2004-04-10 21:01               ` Georg Bauhaus
@ 2004-04-10 21:16               ` Georg Bauhaus
  2004-04-11 13:20                 ` exception parameters Stephen Leake
  2004-04-11 10:31               ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov
  2 siblings, 1 reply; 90+ messages in thread
From: Georg Bauhaus @ 2004-04-10 21:16 UTC (permalink / raw)


Wojtek Narczynski <wojtek@power.com.pl> wrote:
:   raise Bang( Hard, Urgent, -1);

Isn't this just a work around a message passing technique?
If I have a task that may fail in a few hundred ways, and
I know another service task that can deal with these errors, 
I just say attention_please( Hard, Urgent, -1); to this task,
and then abort the first, for example.

Absent tasks, if I jump long with parameters, doesn't this parameter
passing mechanism for "exceptional gotos" create a situation where
program flow is just as hard to follow, or even more so because
the tasking protocol won't be taken into account?



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-10 13:52           ` Jacob Sparre Andersen
@ 2004-04-11  2:45             ` Hyman Rosen
  2004-04-11 10:14               ` Expressing physical units Jacob Sparre Andersen
  2004-04-12  6:58               ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Russ
  2004-04-13  9:53             ` Wojtek Narczynski
  1 sibling, 2 replies; 90+ messages in thread
From: Hyman Rosen @ 2004-04-11  2:45 UTC (permalink / raw)


Jacob Sparre Andersen wrote:
> It should be noted that my analysis was tied rather strongly to Ada,
> and a more relaxed programming language might be able to do something
> that would be sufficiently close to full compile-time unit checking.

C++ can do full compile-time unit checking with no runtime overhead
as long as all units needed by the program are known at compile-time.
The technique uses templates, requires automatic instantiation of
templates for usability (and so cannot be done in Ada), and was published
in Barton & Nackman, _Scientific and Engineering C++_. I've often posted
the technique, but here goes again, in a simplified version:

template <int Mass, int Distance, int Time>
struct Unit
{
     double value;
     Unit(double value = 0.0) : value(value) { }

     Unit operator+(Unit other) { return Unit(value + other.value); }
};

template <int M1, int D1, int T1,
           int M2, int D2, int T2>
Unit<M1+M2,D1+D2,T1+T2>
operator*(Unit<M1,D1,T1> l, Unit<M2,D2,T2> r)
{
     return Unit<M1+M2,D1+D2,T1+T2>(l.value * r.value);
}

This supports positive and negative whole number powers. For those rare
applications which require fractional powers, you can move to using pairs
of numerator/denominator template parameters to represent fractions.
The full implementation will include the other operators, and may have the
value type as a template parameter as well, but this is enough of a guide
to see how it works.

Here's how you might write the output operator:
     template <typename OStream, int M, int D, int T>
     Ostream &operator<<(Ostream &o, const Unit<M, D, T> &v)
     {
         o << v.value;
         if (M > 0) o << " g";
         if (M > 1) o << "^" << M;
         if (D > 0) o << " cm";
         if (D > 1) o << "^" << D;
         if (T > 0) o << " s";
         if (T > 1) o << "^" << T;
         if (M < 0 || D < 0 || T < 0) o << " /";
         if (M < 0) o << " g";
         if (M < 1) o << "^" << -M;
         if (D < 0) o << " cm";
         if (D < 1) o << "^" << -D;
         if (T < 0) o << " s";
         if (T < 1) o << "^" << -T;
         return o;
     }
Because M, D, T are template parameters, their values are all known at
compile time, and the output routine instantiated for a particular unit
will contain only the code needed, without any tests at runtime.



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

* Re: Expressing physical units
  2004-04-11  2:45             ` Hyman Rosen
@ 2004-04-11 10:14               ` Jacob Sparre Andersen
  2004-04-11 16:05                 ` Hyman Rosen
  2004-04-12  6:58               ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Russ
  1 sibling, 1 reply; 90+ messages in thread
From: Jacob Sparre Andersen @ 2004-04-11 10:14 UTC (permalink / raw)


Hyman Rosen wrote:
> Jacob Sparre Andersen wrote:

> > It should be noted that my analysis was tied rather strongly to
> > Ada, and a more relaxed programming language might be able to do
> > something that would be sufficiently close to full compile-time
> > unit checking.
> 
> C++ can do full compile-time unit checking with no runtime overhead
> as long as all units needed by the program are known at
> compile-time.

Yes.  I am aware of that. - And that it is a much more elegant
solution than the one I use do to do the same thing in Ada (in Ada you
actually have to specify _each_ of the units you are going to use
explicitly).

> The technique uses templates, requires automatic instantiation of
> templates for usability (and so cannot be done in Ada),

Yes.

I don't understand C++ templates well enough to be able to see if it
is realistic to copy enough of it to Ada, to allow the easier handling
of compile-time unit checking available in C++.  I am afraid it would
give too many unwanted possibilities in Ada, but it is very tempting.

> and was published in Barton & Nackman, _Scientific and Engineering
> C++_. I've often posted the technique, but here goes again, in a
> simplified version:

[...]

Thanks.

Jacob
-- 
�USA fights for the right of the individual.�
�Yes.  Those of the individual George W. Bush.�
                                     -- with thanks to Olfax



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10 15:35             ` Wojtek Narczynski
  2004-04-10 21:01               ` Georg Bauhaus
  2004-04-10 21:16               ` Georg Bauhaus
@ 2004-04-11 10:31               ` Dmitry A. Kazakov
  2004-04-12 22:02                 ` Randy Brukardt
  2004-04-13  9:30                 ` Wojtek Narczynski
  2 siblings, 2 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-11 10:31 UTC (permalink / raw)


Wojtek Narczynski wrote:

>> This has nothing to do with abstraction inversion.
> 
> Would you please take care to explain to me, what abstraction
> inversion is, according to you? For me abstraction inversion is when
> you need to build low level primitives from high level primitives
> (built on low level primitives), because the high level primitives are
> not expressive enough.

or because of using them in an inappropriate way?

However it is questionable, whether protected objects have a higher level of
abstraction than semaphores. They are more generic but no less fundamental.

>> The problem here is that Ada does not have multiple
>> protected actions.
> 
> Google has not heard of "multiple protected actions", neither have I.

ARM 9.5.1 defines "protected action"

> But I think know what you mean, for my own needs I was calling this
> "compound protected". It seems to require proper tail recursion to
> work.

What I meant is the following. Presently one can define an entry to only of
one protected object or task.

Provided that:

1) protected object and tasks would be tagged (inheritable from);
2) multiple inheritance would be supported;
3) entries, procedures and functions would be primitive operations;
4) functional notation would be permitted (instead of prefix notation)

one could have entries of multiple protected objects and tasks. A call to
such entry would start multiple protected actions (one per each protected
object parameter) and multiple rendezvous (one per each task object
parameter). Could we agree that 1-4 is a damn *lot* of work?

BTW, for your protected counters example, (4) would be enough:

protected type Counter is
   procedure Inc; -- Increments this counter
private
   Value : Integer := 0;
end Counter;

procedure Inc_One (First : in out Counter);
   -- Same as Inc, but uses functional notation
procedure Inc_Two (First, Second : in out Counter);
   -- Increments two counters atomically, starts two protected actions,
   -- one per argument

> At least we seem to agree that Ada concurrency features also have
> warts.

I do not see them as warts. Nothing is inherently wrong with them. They
might be extended in a consistent way to make the language more regular
(see 1-4). Make an AI and send it to ARG! (:-))

>> This is wrong:
>> 
>> http://home.t-online.de/home/Christ-Usch.Grein/Ada/Dimension.html
>> 
>> The type system is capable to express dimensioned units.
> 
> By "express" I don't mean bent over in an such a way that your
> compiler checked your units for you, nor have your compiler mostly
> check your units for you, nor write yet another compiler to work on
> top of your compiler. I mean have your compiler statically check your
> units for you.
> 
> I am afraid that this link show exactly that I am, unfortunately,
> right. The two compile time solutions are: 1. "Checks in assignments
> concerning physical dimensions are not performed.", 2. From what I've
> been able to understand Macks has a language, which compiles to Ada.

First of all I do not count compile time solutions for true solutions. A
true one would include an ability to work with dimensioned values which
units are unknown at compile time. A simpliest possible example is to write
a physicist calculator.

So to solve the problem one should either use tagged types or discriminated
ones. And this indeed works in Ada.

Now to static checks. Nothing in Ada prevents a compiler to from checking
discriminants or type tags statically.

What I see as a real problem is that neither discriminants nor type tags can
be removed from an object if they are statically known. On the contrary
array bounds are indeed removed.

So again, we have more fundamental and complex problem than just "let's
remove a wart".

>> > From the language? For example parameters for exceptions.
>> 
>> How they could have parameters? There are only two ways for dealing
>> with  exceptions. Either 1) all of them are of one [specific] type
>> (maybe an implicit one) or 2) they are of different types (maybe
>> rooted in the same root type [class-wide approach]).
> 
> You seem to be very well educated in Matematics. Thus you know that
> inexistence proofs are among the hardest. Please don't provoke me to
> ask you to proove that there are only two ways of dealing with
> exceptions.

OK, there are only two ways I know of, if you find a third way...

> And once you assume false, you can prove anything.
>
>> Ada has 1), which excludes parameters. If you think that 2) would be
>> better for Ada then solve the following:
> 
> You assumed that the root type for Exception would be tagged record.

See above, either you derive a new type or not. There is no third way.

> Indeed with this assumption it may be hard to maintain the conceptual
> integrity of the language. But I think this level of parametrization
> is an overkill. I'd rather use something like "discriminated records
> with discriminants only".

How it differs from (2)? You just replaced the official mechanism of
inheritance with some hard-wired other. Discriminants are just special kind
of members.

> Here is a version to start with (which actually compiles and "works"):
> 
> generic
> package Crazy is
>    Bang: exception;
>    function T return Boolean;
> end Crazy;
>
[...]  
>  
> package body Crazy is
>    function T return Boolean is begin return True; end T;
> begin
>    raise Bang( Hard, Urgent, -1);
> end Crazy;
> 
> with Crazy;
> procedure Sample is
>    package Catch_It is new Crazy;
> begin
>    null;
> exception
>    when B : Catch_It.Bang =>

This won't work. The exception out of Catch_It will be propagated *after*
"end Sample". So you cannot catch it here! In any point you could, the type
B will be already finalized. So you would have a zombie object of an
unexisting type.

>       -- Here you'd be are able to access the values,
>       -- but not to call anything from the already gone package.
>       -- Regarding scope it is not any differnt from the previous
>       -- example - we were also accessing Bang in hander.
>       Put_Line (B.Severity);
>       Put_Line (B.Urgency);
>       Put_Line (B.Native_Code);
> end Sample;

As I said, because it is in fact (2) it has all its problems:

generic
package Crazy is
   exception Bang (Times : access Integer);
end Crazy;

package body Crazy is
   I : aliased Integer := 0; 
begin
   raise Bang (I'Access);
end Crazy;

> Please note that this actually works in Modula-3, but you are only
> limited to one parameter. Well, all languages have their warts.

This works in C++ too, because all functions and types are global there. I'd
better stick to Ada's way.

> GNAT.Sockets is perhaps the best example how the code could benefit
> from parametrized exceptions. There you have Socket_Error and that's
> it. You need to use compiler specific tricks to extract more info. Or
> you can declare a coule dozen of different exceptions. Or a couple
> hundred, it depends.

Why (1) cannot work here? The only real problem with (1) I can see, is that
the exception type does not have ranges or other forms of subsets. One need
some syntactic suggar to define a set of exceptions which could be then
named in "when".

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10 20:50                 ` Georg Bauhaus
@ 2004-04-11 10:31                   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-11 10:31 UTC (permalink / raw)


Georg Bauhaus wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> 
> :  The only reasonable use of an access parameter is to have "in out"
> : where it is not allowed.
> 
> Access parameters go well with access discriminants...?

Yes, but

1) .all works fine. If that is too much to type one could make access types
more transparent.

2) why don't we have discriminants of any type? In many cases discriminants
are used just because of absence of MI.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: exception parameters
  2004-04-10 21:16               ` Georg Bauhaus
@ 2004-04-11 13:20                 ` Stephen Leake
  2004-04-12 10:29                   ` Dmitry A. Kazakov
  2004-04-13  8:04                   ` Jean-Pierre Rosen
  0 siblings, 2 replies; 90+ messages in thread
From: Stephen Leake @ 2004-04-11 13:20 UTC (permalink / raw)
  To: comp.lang.ada

Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> writes:

> Wojtek Narczynski <wojtek@power.com.pl> wrote:
> :   raise Bang( Hard, Urgent, -1);
> 
> Absent tasks, if I jump long with parameters, doesn't this parameter
> passing mechanism for "exceptional gotos" create a situation where
> program flow is just as hard to follow, or even more so because
> the tasking protocol won't be taken into account?

Yes, it could be abused.

But there are places where it would be useful. 

For example, I'm working on a database GUI. The low-level database
interface raises Database_Error with a string parameter. I have to
parse the string to get the actual database error code. It would be
simpler, and actually clearer, if the error code were avaialble as a
parameter.

I understand there are lots of difficult implementation issues with
general exception parameters, and it can certainly be carried too far.

Ada allows one string parameter for exceptions. If it also allowed one
integer parameter, that might be a nice compromise :).

-- 
-- Stephe




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

* Re: Expressing physical units
  2004-04-11 10:14               ` Expressing physical units Jacob Sparre Andersen
@ 2004-04-11 16:05                 ` Hyman Rosen
  0 siblings, 0 replies; 90+ messages in thread
From: Hyman Rosen @ 2004-04-11 16:05 UTC (permalink / raw)


Jacob Sparre Andersen wrote:
> I don't understand C++ templates well enough to be able to see if it
> is realistic to copy enough of it to Ada, to allow the easier handling
> of compile-time unit checking available in C++.  I am afraid it would
> give too many unwanted possibilities in Ada, but it is very tempting.

The main problem with adopting this feature in Ada is Ada's lack of
automatic instantiation of generics. This arises in the multiplicative
operators. If you look at how I wrote operator*, you'll see that it
synthesizes a return type by adding the corresponding template parameters
of the operands. In use, you simply multiply a pair of units together and
the result has the correct type and can participate in further operations.

The MACKS package that people talk about here uses the same techniques to
represent units without overhead, but it does a whole bunch of explicit
instantiations to make them ready for use. If it happens to miss some needed
versions, it needs to be reconfigured to generate them.



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-11  2:45             ` Hyman Rosen
  2004-04-11 10:14               ` Expressing physical units Jacob Sparre Andersen
@ 2004-04-12  6:58               ` Russ
  2004-04-12 10:29                 ` Dmitry A. Kazakov
  1 sibling, 1 reply; 90+ messages in thread
From: Russ @ 2004-04-12  6:58 UTC (permalink / raw)


Hyman Rosen <hyrosen@mail.com> wrote in message news:<ij2ec.22694$1y1.20221@nwrdny03.gnilink.net>...
> Jacob Sparre Andersen wrote:
> > It should be noted that my analysis was tied rather strongly to Ada,
> > and a more relaxed programming language might be able to do something
> > that would be sufficiently close to full compile-time unit checking.
> 
> C++ can do full compile-time unit checking with no runtime overhead
> as long as all units needed by the program are known at compile-time.
> The technique uses templates, requires automatic instantiation of
> templates for usability (and so cannot be done in Ada), and was published
> in Barton & Nackman, _Scientific and Engineering C++_. I've often posted
> the technique, but here goes again, in a simplified version:

Just for my own education, would you mind explaining why it cannot be
done in a usable way in Ada? Is it because you need a sizable chunk of
instantiation code at the top of each source file that is to use it?
If so, isn't there some trick to get around it?

By the way, I work in the field of air traffic management (ATM), and
I'd really like to see a practical way to guarantee units consistency.
The general mks system is inappropriate for ATM. The traditional units
for ATM are nautical miles (nmi) for horizontal length, and feet (ft)
for altitude. That won't change in our lifetimes -- and probably
never. As for time, it can be in seconds, minutes, or hours.
Horizontal speed in usually given in terms of knots (kn), which is
nmi/hr, but altitude rate is usually given in terms of ft/min. Heading
is normally given in degrees.

In my experience, the most common units problem is confusion between
degrees and radians. Radians are preferable for use inside programs,
but degrees are preferable for I/O. This problem really needs to be
licked once and for all. The next most common problem I find is that
altitude is alternately expressed in terms of ft, hundreds of ft, or
thousands of feet. Standard "Flight Levels" are at multiples of 1000
ft, but they are expressed in units of 100 ft. For example, "FL310" is
a pressure altitude of 31,000 ft.

If a practical way could be developed to deal with these basic units,
and perhaps a few others (such as weight), the integrity of ATM
software could be enhanced considerably, I believe. I was working on a
scheme a couple of years ago involving the standard Ada type system,
but I was (and still am) an Ada programming newbie. I think it would
have worked reasonably well, but who am I to say? In any case, my
friggin' hard drive died and I didn't have that particular work backed
up, so its gone.



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

* Re: exception parameters
  2004-04-11 13:20                 ` exception parameters Stephen Leake
@ 2004-04-12 10:29                   ` Dmitry A. Kazakov
  2004-04-13  0:58                     ` Stephen Leake
  2004-04-13  8:04                   ` Jean-Pierre Rosen
  1 sibling, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-12 10:29 UTC (permalink / raw)


Stephen Leake wrote:

> Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> writes:
> 
>> Wojtek Narczynski <wojtek@power.com.pl> wrote:
>> :   raise Bang( Hard, Urgent, -1);
>> 
>> Absent tasks, if I jump long with parameters, doesn't this parameter
>> passing mechanism for "exceptional gotos" create a situation where
>> program flow is just as hard to follow, or even more so because
>> the tasking protocol won't be taken into account?
> 
> Yes, it could be abused.
> 
> But there are places where it would be useful.
> 
> For example, I'm working on a database GUI. The low-level database
> interface raises Database_Error with a string parameter. I have to
> parse the string to get the actual database error code. It would be
> simpler, and actually clearer, if the error code were avaialble as a
> parameter.

A database connection type may have a primitive operation Get_Last_Error. So
when you catch Database_Error and the connection object is still here (why
should it disappear?), you can get a detailed error description from it.
Get_Last_Error could be made task unique, if connection object will be used
concurrently.

> I understand there are lots of difficult implementation issues with
> general exception parameters, and it can certainly be carried too far.
> 
> Ada allows one string parameter for exceptions. If it also allowed one
> integer parameter, that might be a nice compromise :).

But the exception is already a sort of number. Why not to allow ranges?

Connection_Lost_Error, SQL_Syntax_Error, Unknown_DB_Error : exception;
   -- A consequent set of exceptions
Database_Error renames range Connection_Lost_Error..Unknown_DB_Error;

or

subtype Database_Error is range Connection_Lost_Error..Unknown_DB_Error;
   -- A range of exceptions

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-12  6:58               ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Russ
@ 2004-04-12 10:29                 ` Dmitry A. Kazakov
  2004-04-13  6:52                   ` Russ
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-12 10:29 UTC (permalink / raw)


Russ wrote:

> By the way, I work in the field of air traffic management (ATM), and
> I'd really like to see a practical way to guarantee units consistency.
> The general mks system is inappropriate for ATM. The traditional units
> for ATM are nautical miles (nmi) for horizontal length, and feet (ft)
> for altitude. That won't change in our lifetimes -- and probably
> never. As for time, it can be in seconds, minutes, or hours.
> Horizontal speed in usually given in terms of knots (kn), which is
> nmi/hr, but altitude rate is usually given in terms of ft/min. Heading
> is normally given in degrees.
> 
> In my experience, the most common units problem is confusion between
> degrees and radians. Radians are preferable for use inside programs,
> but degrees are preferable for I/O. This problem really needs to be
> licked once and for all.

It does not differ from [m] vs. [ft]. The dimension of radian is [1] =
m**0*A**0*s**0... The dimension of degree is [Pi/180]. No magic here. More
difficult is Celsius degree vs. K, which AFAIK cannot be solved using C++
templates.

> The next most common problem I find is that
> altitude is alternately expressed in terms of ft, hundreds of ft, or
> thousands of feet. Standard "Flight Levels" are at multiples of 1000
> ft, but they are expressed in units of 100 ft. For example, "FL310" is
> a pressure altitude of 31,000 ft.

See above.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-11 10:31               ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov
@ 2004-04-12 22:02                 ` Randy Brukardt
  2004-04-13 10:56                   ` Dmitry A. Kazakov
  2004-04-13  9:30                 ` Wojtek Narczynski
  1 sibling, 1 reply; 90+ messages in thread
From: Randy Brukardt @ 2004-04-12 22:02 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:c5b6pt$2pcs4d$2@ID-77047.news.uni-berlin.de...
...
> Provided that:
>
> 1) protected object and tasks would be tagged (inheritable from);
> 2) multiple inheritance would be supported;
> 3) entries, procedures and functions would be primitive operations;
> 4) functional notation would be permitted (instead of prefix notation)

See AI-345, which extends the interface mechanism (itself a Ada 200y
proposal) to cover task and protected types. (1) is true if the PT or TT
inherits from one or more interfaces; (2) follows from the definition of
interfaces; (3) is true for calls through interfaces (as opposed to directly
to the PO or TOs); (4) is true for calls through interfaces.

> one could have entries of multiple protected objects and tasks.

I don't see how this follows from (1) to (4), though. Each call is just a
dispatching call to a single operation; there is no implementation
inheritance.

> A call to such entry would start multiple protected actions (one per each
protected
> object parameter) and multiple rendezvous (one per each task object
> parameter). Could we agree that 1-4 is a damn *lot* of work?

Not really. *Interfaces* is a lot of work, but presuming that we're going to
have those anyway, adding protected and task support to them is not a
significant increment.

                 Randy.







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

* Re: exception parameters
  2004-04-12 10:29                   ` Dmitry A. Kazakov
@ 2004-04-13  0:58                     ` Stephen Leake
  2004-04-13  1:30                       ` Randy Brukardt
  0 siblings, 1 reply; 90+ messages in thread
From: Stephen Leake @ 2004-04-13  0:58 UTC (permalink / raw)
  To: comp.lang.ada

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

> A database connection type may have a primitive operation Get_Last_Error. So
> when you catch Database_Error and the connection object is still here (why
> should it disappear?), you can get a detailed error description from it.
> Get_Last_Error could be made task unique, if connection object will be used
> concurrently.

Yes, you _could_ do it that way. But embedding the information in the
exception message is better; there are no global variables involved,
so there are no tasking issues. It would be even better if you could
embed a type other than string, but that's not as much gain.

> > I understand there are lots of difficult implementation issues
> > with general exception parameters, and it can certainly be carried
> > too far.
> > 
> > Ada allows one string parameter for exceptions. If it also allowed one
> > integer parameter, that might be a nice compromise :).
> 
> But the exception is already a sort of number. Why not to allow ranges?
> 
> Connection_Lost_Error, SQL_Syntax_Error, Unknown_DB_Error : exception;
>    -- A consequent set of exceptions
> Database_Error renames range Connection_Lost_Error..Unknown_DB_Error;
> 
> or
> 
> subtype Database_Error is range Connection_Lost_Error..Unknown_DB_Error;
>    -- A range of exceptions

An actual 64 bit number encodes much more information.

-- 
-- Stephe




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

* Re: exception parameters
  2004-04-13  0:58                     ` Stephen Leake
@ 2004-04-13  1:30                       ` Randy Brukardt
  0 siblings, 0 replies; 90+ messages in thread
From: Randy Brukardt @ 2004-04-13  1:30 UTC (permalink / raw)


"Stephen Leake" <stephen_leake@acm.org> wrote in message
news:mailman.247.1081817939.327.comp.lang.ada@ada-france.org...
...
> Yes, you _could_ do it that way. But embedding the information in the
> exception message is better; there are no global variables involved,
> so there are no tasking issues. It would be even better if you could
> embed a type other than string, but that's not as much gain.

Right, which is why the ARG decided not to pursue enhancements in this area.
There was a nice proposal, but it ran into the lifetime issues mentioned
previously, and also had bizzare effects on the Ada.Exceptions package (we
don't want to make existing Ada code wrong!) and we ran out of energy to
address this.

The "range of exceptions" idea was part of that proposal, and I was sorry to
see that go, but it just didn't seem important enough.

                        Randy.






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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-12 10:29                 ` Dmitry A. Kazakov
@ 2004-04-13  6:52                   ` Russ
  2004-04-13 10:55                     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 90+ messages in thread
From: Russ @ 2004-04-13  6:52 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:<c5dr33$gkic$3@ID-77047.news.uni-berlin.de>...
> Russ wrote:
> 
> > By the way, I work in the field of air traffic management (ATM), and
> > I'd really like to see a practical way to guarantee units consistency.
> > The general mks system is inappropriate for ATM. The traditional units
> > for ATM are nautical miles (nmi) for horizontal length, and feet (ft)
> > for altitude. That won't change in our lifetimes -- and probably
> > never. As for time, it can be in seconds, minutes, or hours.
> > Horizontal speed in usually given in terms of knots (kn), which is
> > nmi/hr, but altitude rate is usually given in terms of ft/min. Heading
> > is normally given in degrees.
> > 
> > In my experience, the most common units problem is confusion between
> > degrees and radians. Radians are preferable for use inside programs,
> > but degrees are preferable for I/O. This problem really needs to be
> > licked once and for all.
> 
> It does not differ from [m] vs. [ft]. The dimension of radian is [1] =
> m**0*A**0*s**0... The dimension of degree is [Pi/180]. No magic here. More
> difficult is Celsius degree vs. K, which AFAIK cannot be solved using C++
> templates.

I know it can be done in C++, but I thought we were talking about doing it in Ada.

By the way, what the heck is "m**0*A**0*s**0..."?

> > The next most common problem I find is that
> > altitude is alternately expressed in terms of ft, hundreds of ft, or
> > thousands of feet. Standard "Flight Levels" are at multiples of 1000
> > ft, but they are expressed in units of 100 ft. For example, "FL310" is
> > a pressure altitude of 31,000 ft.
> 
> See above.



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

* Re: exception parameters
  2004-04-11 13:20                 ` exception parameters Stephen Leake
  2004-04-12 10:29                   ` Dmitry A. Kazakov
@ 2004-04-13  8:04                   ` Jean-Pierre Rosen
  1 sibling, 0 replies; 90+ messages in thread
From: Jean-Pierre Rosen @ 2004-04-13  8:04 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 800 bytes --]


"Stephen Leake" <stephen_leake@acm.org> a �crit dans le message de news:mailman.240.1081689629.327.comp.lang.ada@ada-france.org...
> For example, I'm working on a database GUI. The low-level database
> interface raises Database_Error with a string parameter. I have to
> parse the string to get the actual database error code. It would be
> simpler, and actually clearer, if the error code were avaialble as a
> parameter.
>
If my program is not multi-tasked, I just store the error context in some global variables of the package, with accessor functions.
If it is multi-tasked, I use task attributes.
No need for exception parameters here.

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr





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

* Re: Reprise: 'in out' parameters for functions
  2004-04-11 10:31               ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov
  2004-04-12 22:02                 ` Randy Brukardt
@ 2004-04-13  9:30                 ` Wojtek Narczynski
  2004-04-13 12:00                   ` Dmitry A. Kazakov
  1 sibling, 1 reply; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-13  9:30 UTC (permalink / raw)


Dimitry,

You silently refused to say what abstraction inversion is according to
you :-)

> However it is questionable, whether protected objects have a higher level of
> abstraction than semaphores. They are more generic but no less fundamental.

Well, let's look at them as manual (semaphores) vs. automated
(protected objects).

> BTW, for your protected counters example, (4) would be enough:
> 
> protected type Counter is
>    procedure Inc; -- Increments this counter
> private
>    Value : Integer := 0;
> end Counter;
> 
> procedure Inc_One (First : in out Counter);
>    -- Same as Inc, but uses functional notation
> procedure Inc_Two (First, Second : in out Counter);
>    -- Increments two counters atomically, starts two protected actions,
>    -- one per argument

Cool. 

> First of all I do not count compile time solutions for true solutions. A
> true one would include an ability to work with dimensioned values which
> units are unknown at compile time. A simpliest possible example is to write
> a physicist calculator.

Then we're talking about two distinct things. I am talking about a
compile time solution only.

> OK, there are only two ways I know of, if you find a third way...

The first way can be viewed as an incarnation of the second. 

Or you can ensure that there are no runtime exceptions.

> How it differs from (2)? You just replaced the official mechanism of
> inheritance with some hard-wired other. Discriminants are just special kind
> of members.

It differst in that it can be implemented, because there are no
pointers to inexistent trampolines, only (immutable, integer) values.

> This won't work. The exception out of Catch_It will be propagated *after*
> "end Sample". So you cannot catch it here! In any point you could, the type
> B will be already finalized. So you would have a zombie object of an
> unexisting type.

Well, this is how it goes with exceptions. That's why the "type"
should be limited (in ordinary sense) to only: declaration, raising /
construction, catching and extracting immutable values in handlers.

> Why (1) cannot work here? The only real problem with (1) I can see, is that
> the exception type does not have ranges or other forms of subsets. One need
> some syntactic suggar to define a set of exceptions which could be then
> named in "when".

Feel free to perceive my 'code' as syntactic sugar.

Regards,
Wojtek



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-10 13:52           ` Jacob Sparre Andersen
  2004-04-11  2:45             ` Hyman Rosen
@ 2004-04-13  9:53             ` Wojtek Narczynski
  2004-04-15 21:27               ` Expressing physical units Jacob Sparre Andersen
  1 sibling, 1 reply; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-13  9:53 UTC (permalink / raw)


Jacob,

> One of my programs disagrees somewhat with your statement.  I switched
> from run-time to compile-time checking of unit mismatches, when a
> recent version of Macks made it practical to start using compile-time
> checks.

Macks is not Ada, okay? 
But I will take a closer look at how it works.

> Are you sure that "matchcad" actually did full compile-time unit
> checking?

Hehe, I am sure that it did not.

Regards,
Wojtek



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-13  6:52                   ` Russ
@ 2004-04-13 10:55                     ` Dmitry A. Kazakov
  2004-04-14  4:50                       ` Hyman Rosen
  2004-04-14  7:10                       ` Russ
  0 siblings, 2 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-13 10:55 UTC (permalink / raw)


Russ wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:<c5dr33$gkic$3@ID-77047.news.uni-berlin.de>...
>> Russ wrote:
>> 
>> > By the way, I work in the field of air traffic management (ATM), and
>> > I'd really like to see a practical way to guarantee units consistency.
>> > The general mks system is inappropriate for ATM. The traditional units
>> > for ATM are nautical miles (nmi) for horizontal length, and feet (ft)
>> > for altitude. That won't change in our lifetimes -- and probably
>> > never. As for time, it can be in seconds, minutes, or hours.
>> > Horizontal speed in usually given in terms of knots (kn), which is
>> > nmi/hr, but altitude rate is usually given in terms of ft/min. Heading
>> > is normally given in degrees.
>> > 
>> > In my experience, the most common units problem is confusion between
>> > degrees and radians. Radians are preferable for use inside programs,
>> > but degrees are preferable for I/O. This problem really needs to be
>> > licked once and for all.
>> 
>> It does not differ from [m] vs. [ft]. The dimension of radian is [1] =
>> m**0*A**0*s**0... The dimension of degree is [Pi/180]. No magic here.
>> More difficult is Celsius degree vs. K, which AFAIK cannot be solved
>> using C++ templates.
> 
> I know it can be done in C++, but I thought we were talking about doing it
> in Ada.
> 
> By the way, what the heck is "m**0*A**0*s**0..."?

Any unit system is built upon some standard set of measures (base units).
This set is pretty arbitrary from a physics point of view, but in SI it was
selected to be m, A, s, kg, K, cd, mol. A dimension of any derived unit is
then a product of powers of the base units. For example, the dimension of
acceleration is m*s**(-2). When all powers are 0, we have a "dimensionless"
unit, like radian is.

Now to templates and C++. You are wrong thinking that units can be properly
done in C++. What indeed can be, is a tiny part of what is really
necessary. Consider the following issues:

1. Shifted units, like Celsius degree.
2. Dealing with units unknown at compile time. How would you communicate
with a data base, or develop a gauge widget, or write a unit calculator?
How to write a unit I/O package?
3. Dealing with multiple unit systems. The C++ solution actually works in
SI. It means that a measure in [ft] has to be converted to [m]. It is OK as
long as:
3.a. There is no range problems. In an emedded system one could use a fixed
arithmetics with would overflow if the distance is measured in [m], but
work fine for [km].
3.b. One can ignore inevitable precission loss caused by unit conversions.
This might be critical for some applications.
5. How to handle logarithmic units and other non-linear scales?
6. Container problem. Surely a vector, matrix etc of dimensioned values
should have a dimension. Possibly it could be handled by templates, but I
am afraid it would not be so easy.
7. Any generic (template) solution would make everything based upon it also
generic.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-12 22:02                 ` Randy Brukardt
@ 2004-04-13 10:56                   ` Dmitry A. Kazakov
  2004-04-14 21:12                     ` Randy Brukardt
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-13 10:56 UTC (permalink / raw)


Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:c5b6pt$2pcs4d$2@ID-77047.news.uni-berlin.de...
> ...
>> Provided that:
>>
>> 1) protected object and tasks would be tagged (inheritable from);
>> 2) multiple inheritance would be supported;
>> 3) entries, procedures and functions would be primitive operations;
>> 4) functional notation would be permitted (instead of prefix notation)
> 
> See AI-345, which extends the interface mechanism (itself a Ada 200y
> proposal) to cover task and protected types. (1) is true if the PT or TT
> inherits from one or more interfaces; (2) follows from the definition of
> interfaces; (3) is true for calls through interfaces (as opposed to
> directly to the PO or TOs); (4) is true for calls through interfaces.
> 
>> one could have entries of multiple protected objects and tasks.
> 
> I don't see how this follows from (1) to (4), though. Each call is just a
> dispatching call to a single operation; there is no implementation
> inheritance.

Yes, but if I could have two dispatching parameters of same protected type
(no MD involved) in a primitive operation, then a call to it should start
two protected actions. Same with task entries, (4) should allow something
like:

task type Foo is ... end Foo;
entry Double_Rendezvous (X, Y : in out Foo);
   -- Declared after "end Foo";

task body Foo is
begin
   loop
      accept Double_Rendezvouz;
         -- Cannot give the body here
   end loop;
end Foo;

entry Double_Rendezvouz (X, Y : in out Foo) is
begin
   ...
end Double_Rendezvouz;

[ I cannot see any direct use of things like that, except for demonstrating
race conditions to students (:-)), but who knows... ]

>> A call to such entry would start multiple protected actions (one per each
> protected
>> object parameter) and multiple rendezvous (one per each task object
>> parameter). Could we agree that 1-4 is a damn *lot* of work?
> 
> Not really. *Interfaces* is a lot of work, but presuming that we're going
> to have those anyway, adding protected and task support to them is not a
> significant increment.

I am glad to hear it from you, because of course, you know it better.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-13  9:30                 ` Wojtek Narczynski
@ 2004-04-13 12:00                   ` Dmitry A. Kazakov
  2004-04-13 22:41                     ` Wojtek Narczynski
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-13 12:00 UTC (permalink / raw)


Wojtek Narczynski wrote:

> Dimitry,
> 
> You silently refused to say what abstraction inversion is according to
> you :-)

We can use your definition if you want. (:-))

>> First of all I do not count compile time solutions for true solutions. A
>> true one would include an ability to work with dimensioned values which
>> units are unknown at compile time. A simpliest possible example is to
>> write a physicist calculator.
> 
> Then we're talking about two distinct things. I am talking about a
> compile time solution only.

Why should they be distinct? The key advantage of Ada strings as compared to
Pascal ones, is that they works in both static and dynamic cases. Why units
should be handled otherwise? How would you then mix both approaches in one
program? In my view a real solution should respond the requirements I
mentioned in another thread answering Russ.

>> OK, there are only two ways I know of, if you find a third way...
> 
> The first way can be viewed as an incarnation of the second.

Surely the second way is more general.

> Or you can ensure that there are no runtime exceptions.

I didn't say that (2) is not solvable. I just invited you to think about it
more deeply, before making some final statements. For example, one could
make the exception object mutating to its parent type, when the exception
type goes out of scope. This would then influnce the language. In which
way? What are the consequences, I mean all consequences, etc.

>> How it differs from (2)? You just replaced the official mechanism of
>> inheritance with some hard-wired other. Discriminants are just special
>> kind of members.
> 
> It differst in that it can be implemented, because there are no
> pointers to inexistent trampolines, only (immutable, integer) values.

Discriminants can be of access types.

>> This won't work. The exception out of Catch_It will be propagated *after*
>> "end Sample". So you cannot catch it here! In any point you could, the
>> type B will be already finalized. So you would have a zombie object of an
>> unexisting type.
> 
> Well, this is how it goes with exceptions. That's why the "type"
> should be limited (in ordinary sense) to only: declaration, raising /
> construction, catching and extracting immutable values in handlers.

Here you create a new class of types, limited in some particular way. Doing
so, you have to precisely define this class, you have to name it, you have
to consider types other than exceptions of being of this class, you have to
give it a formal name for generics and so on and so far. And in the end you
have to answer some newbie, why Ada does it that complex!

>> Why (1) cannot work here? The only real problem with (1) I can see, is
>> that the exception type does not have ranges or other forms of subsets.
>> One need some syntactic suggar to define a set of exceptions which could
>> be then named in "when".
> 
> Feel free to perceive my 'code' as syntactic sugar.

It is not (1) it is (2), which has a lot of problems.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-07 20:31 Stephen Leake
  2004-04-08 18:42 ` Georg Bauhaus
@ 2004-04-13 14:45 ` Robert I. Eachus
  1 sibling, 0 replies; 90+ messages in thread
From: Robert I. Eachus @ 2004-04-13 14:45 UTC (permalink / raw)


Stephen Leake wrote:

> This is what I wanted to declare:
> 
> function Parse
>   (Error_Label : in     String;
>    Token       : in out Token_List.List_Iterator)
>   return String;
...
> The work-around is to use a procedure and a bounded string:
> 
>    procedure Parse
>      (Error_Label      : in     String;
>       Token            : in out Token_List.List_Iterator;
>       Config_File_Name :    out OpenToken.Buffers.Bounded_String);

IMHO a better workaround is to use an access parameter:

function Parse
    (Error_Label : in     String;
     Token       : access Token_List.List_Iterator)
    return String;

Yeah, I know, access is not a parameter mode.  But it certainly works 
like one which is why I tend to align access as if it were a mode.

-- 

                                           Robert I. Eachus

"The terrorist enemy holds no territory, defends no population, is 
unconstrained by rules of warfare, and respects no law of morality. Such 
an enemy cannot be deterred, contained, appeased or negotiated with. It 
can only be destroyed--and that, ladies and gentlemen, is the business 
at hand."  -- Dick Cheney




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-13 12:00                   ` Dmitry A. Kazakov
@ 2004-04-13 22:41                     ` Wojtek Narczynski
  2004-04-14  8:49                       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-13 22:41 UTC (permalink / raw)


Dimitry,

>> You silently refused to say what abstraction inversion is according
>> to you :-)

> We can use your definition if you want. (:-))

My impression was that, according to you, mine was wrong. Certainly, I
would prefer to use the right one.

---

>> Then we're talking about two distinct things. I am talking about a
>> compile time solution only.
 
> Why should they be distinct? 

Checking physical units statically would be helpful for high integrity
software. I don't see any practical use for runtime unit checks.

---

> I didn't say that (2) is not solvable. I just invited you to think about it
> more deeply, before making some final statements. 

It is unclear to me what final statements you are referring to.

---

> Discriminants can be of access types.

Good point, my bad.

---

> Here you create a new class of types, limited in some particular way. Doing
> so, you have to precisely define this class, you have to name it, you have
> to consider types other than exceptions of being of this class, you have to
> give it a formal name for generics and so on and so far. And in the end you
> have to answer some newbie, why Ada does it that complex!

Fortunately a distinct class already exists, and it's called
exceptions. I'd only extend it to be able to convey some additional
info down the callstack, but the added complexity is, of course, a
valid point.


Regards,
Wojtek



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-13 10:55                     ` Dmitry A. Kazakov
@ 2004-04-14  4:50                       ` Hyman Rosen
  2004-04-14  8:49                         ` Dmitry A. Kazakov
  2004-04-14  7:10                       ` Russ
  1 sibling, 1 reply; 90+ messages in thread
From: Hyman Rosen @ 2004-04-14  4:50 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> 1. Shifted units, like Celsius degree.

This can be done by adding an extra shift prameter. You would also need
to describe the units system more thoroughly. The standard units can
appear in positive or negative powers, but you obviously cannot do this
with shifted units.

> 2. Dealing with units unknown at compile time. How would you communicate
> with a data base, or develop a gauge widget, or write a unit calculator?

This requires a different solution. But that's OK. If many applications
do not need this dynamic behavior, then they stand to benefit from the
zero-overhead of the given solution.

> How to write a unit I/O package?

I demonstrated that in another post. You write a bunch of 'if' statements
whose conditions depend on the template parameters, and they are all known
at compile-time for a given unit.

> 3. Dealing with multiple unit systems.

You can add a scale factor template parameter for each dimension, and then
they will be different types, so the compiler will prevent you from adding
mm to cm, say. You can also code the conversions as templates. I suspect
it's unwieldy and people would be just as happy to pick one unit system, but
it could be done.

> 5. How to handle logarithmic units and other non-linear scales?

By specializing the templates for these units to do the appropriate operations.
Ada does not have the concept of specialized templates, but C++ does.

> 6. Container problem. Surely a vector, matrix etc of dimensioned values
> should have a dimension.

I don't see why, but that's certainly not a problem for C++. All of the
standard container templates export the type of the object they hold as a
named type called "value_type" so the units of the contained objects are
available if needed.

> 7. Any generic (template) solution would make everything based upon it also
> generic.

Modern C++ programmers see that as an opportunity, not a problem!



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-13 10:55                     ` Dmitry A. Kazakov
  2004-04-14  4:50                       ` Hyman Rosen
@ 2004-04-14  7:10                       ` Russ
  2004-04-14  8:53                         ` tmoran
  2004-04-14  9:21                         ` Dmitry A. Kazakov
  1 sibling, 2 replies; 90+ messages in thread
From: Russ @ 2004-04-14  7:10 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:<c5gh04$1ba02$1@ID-77047.news.uni-berlin.de>...
> Russ wrote:
> 
> > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> > news:<c5dr33$gkic$3@ID-77047.news.uni-berlin.de>...
> >> Russ wrote:
> >> 
> >> > By the way, I work in the field of air traffic management (ATM), and
> >> > I'd really like to see a practical way to guarantee units consistency.
> >> > The general mks system is inappropriate for ATM. The traditional units
> >> > for ATM are nautical miles (nmi) for horizontal length, and feet (ft)
> >> > for altitude. That won't change in our lifetimes -- and probably
> >> > never. As for time, it can be in seconds, minutes, or hours.
> >> > Horizontal speed in usually given in terms of knots (kn), which is
> >> > nmi/hr, but altitude rate is usually given in terms of ft/min. Heading
> >> > is normally given in degrees.
> >> > 
> >> > In my experience, the most common units problem is confusion between
> >> > degrees and radians. Radians are preferable for use inside programs,
> >> > but degrees are preferable for I/O. This problem really needs to be
> >> > licked once and for all.

> Now to templates and C++. You are wrong thinking that units can be properly
> done in C++. What indeed can be, is a tiny part of what is really
> necessary. Consider the following issues:
> 
> 1. Shifted units, like Celsius degree.
> 2. Dealing with units unknown at compile time. How would you communicate
> with a data base, or develop a gauge widget, or write a unit calculator?
> How to write a unit I/O package?
> 3. Dealing with multiple unit systems. The C++ solution actually works in
> SI. It means that a measure in [ft] has to be converted to [m]. It is OK as
> long as:
> 3.a. There is no range problems. In an emedded system one could use a fixed
> arithmetics with would overflow if the distance is measured in [m], but
> work fine for [km].
> 3.b. One can ignore inevitable precission loss caused by unit conversions.
> This might be critical for some applications.
> 5. How to handle logarithmic units and other non-linear scales?
> 6. Container problem. Surely a vector, matrix etc of dimensioned values
> should have a dimension. Possibly it could be handled by templates, but I
> am afraid it would not be so easy.
> 7. Any generic (template) solution would make everything based upon it also
> generic.

You're talking about the Grand Unified system of units. That's fine,
but I'm just talking about something that can make air traffic
management (ATM) software more robust. As I wrote before, the most
important units in ATM are few in number.

Here is an outline of what I was working on in my free time before my
hard drive died. You define a dozen or so Ada types for commonly used
units, such as

nmi (nautical miles)
feet
FL (flight level, or 100 ft)
kft (1000 ft)
deg
rad (radian)
knots
fpm (feet per minute, for altitude rate)
klb (1000 pounds)
sec (second)
minute
hour

and perhaps a few others.

You then define operators for all the likely operations among these
types. Each type can be added to or subtracted from its own type, for
example. When you divide a type by the same type, you get a
dimensionless number. Multiplication of like types is prohibited
unless it really makes sense. If you divide nmi by hour, you get
knots. If you divide nmi by sec, the compiler coughs and tells you
that you can't do that -- so you go and convert the seconds to hours
(using a predefined conversion function). You get the idea.

As new units or combinations come up, you add them into the
repertoire. Perhaps the total number of units and reasonable
combinations would be managable.

The idea here is not to have all units converted automagically but
rather simply to have the compiler catch any potentially inconsistent
use of units. The days of using degrees for radians, or dividing nmi
by sec and adding it to knots, would be mercifully over. And no
generics are needed.

Is this a reasonable approach?



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-13 22:41                     ` Wojtek Narczynski
@ 2004-04-14  8:49                       ` Dmitry A. Kazakov
  2004-04-14 15:03                         ` Wojtek Narczynski
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-14  8:49 UTC (permalink / raw)


Wojtek Narczynski wrote:

>>> You silently refused to say what abstraction inversion is according
>>> to you :-)
> 
>> We can use your definition if you want. (:-))
> 
> My impression was that, according to you, mine was wrong. Certainly, I
> would prefer to use the right one.

I did not disagree with your definition. I did with your statement that
Ada's protected objects are wrong way. They might have problems, though.
But it appeared, as you treating them as completely wrong.

>>> Then we're talking about two distinct things. I am talking about a
>>> compile time solution only.
>  
>> Why should they be distinct?
> 
> Checking physical units statically would be helpful for high integrity
> software. I don't see any practical use for runtime unit checks.

Only because I see no smiley... How would you implement:

procedure Put (Stream : File, Value : Measurement);
procedure Get (Stream : File, Value : out Measurement);

For example, a requirement of one of our customer was to have a button in
his MMI to switch between European and American units in all visual
elements and printouts. Now go, figure out, how would you solve that using
templates. BTW, European /= SI, because of km/h, ps, Celsius degree etc.
Not to forget dozens of external devices all working with units of their
own, all need to be hot pluggable etc.

>> I didn't say that (2) is not solvable. I just invited you to think about
>> it more deeply, before making some final statements.
> 
> It is unclear to me what final statements you are referring to.

That Ada exception model should be replaced by some other.
 
-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-14  4:50                       ` Hyman Rosen
@ 2004-04-14  8:49                         ` Dmitry A. Kazakov
  2004-04-14 16:49                           ` Hyman Rosen
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-14  8:49 UTC (permalink / raw)


Hyman Rosen wrote:

> Dmitry A. Kazakov wrote:
>> 1. Shifted units, like Celsius degree.
> 
> This can be done by adding an extra shift prameter.

But C++ does not allow double as a template parameter.

> You would also need
> to describe the units system more thoroughly. The standard units can
> appear in positive or negative powers, but you obviously cannot do this
> with shifted units.

Why? It is no matter. Shifted units represent linear scales:

x = a * y + b

The dimension of a and b may have any powers.

>> 2. Dealing with units unknown at compile time. How would you communicate
>> with a data base, or develop a gauge widget, or write a unit calculator?
> 
> This requires a different solution. But that's OK. If many applications
> do not need this dynamic behavior, then they stand to benefit from the
> zero-overhead of the given solution.

Because there can be a universal solution with zero-overhead in static case.

>> How to write a unit I/O package?
> 
> I demonstrated that in another post. You write a bunch of 'if' statements
> whose conditions depend on the template parameters, and they are all known
> at compile-time for a given unit.

(:-))

>> 3. Dealing with multiple unit systems.
> 
> You can add a scale factor template parameter for each dimension, and then
> they will be different types, so the compiler will prevent you from adding
> mm to cm, say.

Not that is the problem. One can add 1 [mm] and 1 [cm], it is legal. The
question is in which unit system the arguments are and the result will be.
There could be a need to have both m,s,A,... and mm,h,kA,..., for reasons I
explained before.

>> 5. How to handle logarithmic units and other non-linear scales?
> 
> By specializing the templates for these units to do the appropriate
> operations. Ada does not have the concept of specialized templates, but
> C++ does.

I do not see how you could add x in meters of SI with y in ft of logarithmic
scale using specialized templates. To represent scale you will probably
need some pointer to the scale descriptor in your template.

>> 7. Any generic (template) solution would make everything based upon it
>> also generic.
> 
> Modern C++ programmers see that as an opportunity, not a problem!

I do not see any way of making a GUI or DB interface based on templates.
Consider a distributed system with should have a communication protocol to
exchange physical measures. How would you do it using templates? Consider a
large finite element library. If that has to be used for physical values,
then the whole library has to be generic.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-14  7:10                       ` Russ
@ 2004-04-14  8:53                         ` tmoran
  2004-04-14  9:01                           ` Vinzent 'Gadget' Hoefler
  2004-04-14  9:21                         ` Dmitry A. Kazakov
  1 sibling, 1 reply; 90+ messages in thread
From: tmoran @ 2004-04-14  8:53 UTC (permalink / raw)


>example. When you divide a type by the same type, you get a
>dimensionless number. Multiplication of like types is prohibited
   A "dimensionless number" still has a specific type so that
  alpha : degrees;
  x,y   : feet;
  beta  : radians := x/y+alpha;
is illegal.  So the type system does more than simply keep track of
a set of exponents.

>You then define operators for all the likely operations among these
>types. Each type can be added to or subtracted from its own type, for
  See, for instance, chapter 2 of "Ada in Action" by Do-While Jones,
ISBN 0-471-6078-8, Wiley, 1989 (also available on the internet but I don't
have the URL).



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-14  8:53                         ` tmoran
@ 2004-04-14  9:01                           ` Vinzent 'Gadget' Hoefler
  0 siblings, 0 replies; 90+ messages in thread
From: Vinzent 'Gadget' Hoefler @ 2004-04-14  9:01 UTC (permalink / raw)


tmoran@acm.org wrote:

>  See, for instance, chapter 2 of "Ada in Action" by Do-While Jones,
>ISBN 0-471-6078-8, Wiley, 1989 (also available on the internet but I don't
>have the URL).

<URL:http://www.cs.kuleuven.ac.be/~dirk/ada-belgium/aia/>


Vinzent.



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-14  7:10                       ` Russ
  2004-04-14  8:53                         ` tmoran
@ 2004-04-14  9:21                         ` Dmitry A. Kazakov
  1 sibling, 0 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-14  9:21 UTC (permalink / raw)


Russ wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:<c5gh04$1ba02$1@ID-77047.news.uni-berlin.de>...
>> Russ wrote:
>> 
>> > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> > news:<c5dr33$gkic$3@ID-77047.news.uni-berlin.de>...
>> >> Russ wrote:
>> >> 
>> >> > By the way, I work in the field of air traffic management (ATM), and
>> >> > I'd really like to see a practical way to guarantee units
>> >> > consistency. The general mks system is inappropriate for ATM. The
>> >> > traditional units for ATM are nautical miles (nmi) for horizontal
>> >> > length, and feet (ft) for altitude. That won't change in our
>> >> > lifetimes -- and probably never. As for time, it can be in seconds,
>> >> > minutes, or hours. Horizontal speed in usually given in terms of
>> >> > knots (kn), which is nmi/hr, but altitude rate is usually given in
>> >> > terms of ft/min. Heading is normally given in degrees.
>> >> > 
>> >> > In my experience, the most common units problem is confusion between
>> >> > degrees and radians. Radians are preferable for use inside programs,
>> >> > but degrees are preferable for I/O. This problem really needs to be
>> >> > licked once and for all.
> 
>> Now to templates and C++. You are wrong thinking that units can be
>> properly done in C++. What indeed can be, is a tiny part of what is
>> really necessary. Consider the following issues:
>> 
>> 1. Shifted units, like Celsius degree.
>> 2. Dealing with units unknown at compile time. How would you communicate
>> with a data base, or develop a gauge widget, or write a unit calculator?
>> How to write a unit I/O package?
>> 3. Dealing with multiple unit systems. The C++ solution actually works in
>> SI. It means that a measure in [ft] has to be converted to [m]. It is OK
>> as long as:
>> 3.a. There is no range problems. In an emedded system one could use a
>> fixed arithmetics with would overflow if the distance is measured in [m],
>> but work fine for [km].
>> 3.b. One can ignore inevitable precission loss caused by unit
>> conversions. This might be critical for some applications.
>> 5. How to handle logarithmic units and other non-linear scales?
>> 6. Container problem. Surely a vector, matrix etc of dimensioned values
>> should have a dimension. Possibly it could be handled by templates, but I
>> am afraid it would not be so easy.
>> 7. Any generic (template) solution would make everything based upon it
>> also generic.
> 
> You're talking about the Grand Unified system of units.

Yes.

> That's fine,
> but I'm just talking about something that can make air traffic
> management (ATM) software more robust. As I wrote before, the most
> important units in ATM are few in number.

AFAIK, ATM does not much differ from other MMI. For them run-time unit
checking fits at best, because performance/space requirements are not that
strict.

Here is my implementation:

http://www.dmitry-kazakov.de/ada/units.htm

> Here is an outline of what I was working on in my free time before my
> hard drive died. You define a dozen or so Ada types for commonly used
> units, such as
> 
> nmi (nautical miles)
> feet
> FL (flight level, or 100 ft)
> kft (1000 ft)
> deg
> rad (radian)
> knots
> fpm (feet per minute, for altitude rate)
> klb (1000 pounds)
> sec (second)
> minute
> hour
> 
> and perhaps a few others.

You do not need that much of types. Internally you should work in SI units.
The only place where units appear is MMI readings and controls. A usual way
is to make widgets unit aware and tunable at run time. Here your problems
end. The operator will use ft, m, km, lightyear, whatsoever. It is the
widget property. The result will be always in the corresponding SI unit.

> You then define operators for all the likely operations among these
> types. Each type can be added to or subtracted from its own type, for
> example. When you divide a type by the same type, you get a
> dimensionless number. Multiplication of like types is prohibited
> unless it really makes sense. If you divide nmi by hour, you get
> knots. If you divide nmi by sec, the compiler coughs and tells you
> that you can't do that -- so you go and convert the seconds to hours
> (using a predefined conversion function). You get the idea.

Yes, you are trying to keep several unit system separate. Like meter-second,
knot-hour etc. I only do not see any reason why it should make any sense in
your case.

> As new units or combinations come up, you add them into the
> repertoire. Perhaps the total number of units and reasonable
> combinations would be managable.

You want to manage a geometric explosion...

> The idea here is not to have all units converted automagically but
> rather simply to have the compiler catch any potentially inconsistent
> use of units.

Dividing miles by seconds has a clear physical sense.

> The days of using degrees for radians, or dividing nmi
> by sec and adding it to knots, would be mercifully over.
> And no
> generics are needed.
> 
> Is this a reasonable approach?

It is a possible approach, but I think that for your case run-time checks
are more suitable (for MMI). Only if you have some additional safety
requirements, explicitly stating that all formulae shall be statically
checked, then you can additionally use a compile-time approach, see:

http://home.T-Online.de/home/Christ-Usch.Grein/Ada/Dimension.html

But in any case, you have to switch to SI. Then 80% of your problems will
disappear.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-09 22:48             ` Randy Brukardt
@ 2004-04-14 14:40               ` Robert I. Eachus
  2004-04-14 21:20                 ` Randy Brukardt
  0 siblings, 1 reply; 90+ messages in thread
From: Robert I. Eachus @ 2004-04-14 14:40 UTC (permalink / raw)


Randy Brukardt wrote:

> I agree with all of this too. Also not going to happen. See AI-290, also
> voted "No Action".

On pragma Pure and static expressions, I think that you (Randy) are 
being a little premature.  It may come up again for Ada 1Z.  AI-290 is 
about pragma Pure_Function.

Of course, I think that in out for functions is never going to happen. 
(The idea of making 'Access implicit in some contexts is interesting, 
and may end up allowing the reality without changing the rule.)  If you 
want in out parameters for functions, use GNAT and modify it, or use the 
existing GNAT value returning proceedure pragma.

-- 

                                           Robert I. Eachus

"The terrorist enemy holds no territory, defends no population, is 
unconstrained by rules of warfare, and respects no law of morality. Such 
an enemy cannot be deterred, contained, appeased or negotiated with. It 
can only be destroyed--and that, ladies and gentlemen, is the business 
at hand."  -- Dick Cheney




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-14  8:49                       ` Dmitry A. Kazakov
@ 2004-04-14 15:03                         ` Wojtek Narczynski
  2004-04-15 10:37                           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-14 15:03 UTC (permalink / raw)


> I did not disagree with your definition. I did with your statement that
> Ada's protected objects are wrong way. They might have problems, though.
> But it appeared, as you treating them as completely wrong.

"Wrong" seems to be one of your favourite words. I merely said that
Ada concurrency features are not expressive enough not to require
abstraction inversion in many cases.

---

>> Checking physical units statically would be helpful for high
integrity
>> software. I don't see any practical use for runtime unit checks.
 
> Only because I see no smiley... How would you implement:
> 
> procedure Put (Stream : File, Value : Measurement);
> procedure Get (Stream : File, Value : out Measurement);
> 
> For example, a requirement of one of our customer was to have a button in
> his MMI to switch between European and American units in all visual
> elements and printouts. Now go, figure out, how would you solve that using
> templates.

Huhm, we are talking about _checks_, then we are suddenly talking
about _conversions_. But even for conversions, even though they are
most certainly useful in many cases at runtime, the idea to hardcode
the external representation of values with units into the compiler and
runtime, is unfortunate.

---
 
>>> I didn't say that (2) is not solvable. I just invited you to think
about
>>> it more deeply, before making some final statements.
>> 
>> It is unclear to me what final statements you are referring to.
> 
> That Ada exception model should be replaced by some other.

I hate it when somebody puts words I have not said in my mouth. I
suggest that you proofread your own posts for final statements
instead.


Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10  2:28         ` Wojtek Narczynski
                             ` (2 preceding siblings ...)
  2004-04-10 12:32           ` Wojtek Narczynski
@ 2004-04-14 15:46           ` Robert I. Eachus
  2004-04-16  1:52             ` Wojtek Narczynski
  3 siblings, 1 reply; 90+ messages in thread
From: Robert I. Eachus @ 2004-04-14 15:46 UTC (permalink / raw)


Wojtek Narczynski wrote:

> Or the simplest possible: two protected counters, try to get the sum
> atomically.

Since this is trivial, I can only assume that you have two protected 
counters with no support for external locking in mind.  Actually, you 
can even do that, by having one counter have a Sum operation that calls 
the other.

The fact that two arbitrary counters cannot be added atomically in all 
cases is a feature of the real world, not of Ada. Certainly any two 
counters that can be managed with a P,V protocol can be added 
atomically.  It is also possible if only one counter has P, V support.

However, this whole subject is probably silly.  If I give you a total 
outside of any locking which is guaranteed to have been correct at some 
point in the past, how do you know whether it was atomic or not?  The 
answer has to be that it was possible to increment both counters with an 
atomic operation. (For example, any odd sum could be invalid.)  But once 
we postulate atomic joint increments, atomic sums are obviously also 
possible.

Reminds me of a lot of improvement requests for Ada 9X.  "We want to do 
such and such."

"Well, here is a simple example of how to do it in current Ada."

"Oh, but our software development plan doesn't allow us to use 
Unchecked_Conversion."

Well, fix your bloody SDP, you nit!

Hmm. It sounds harsh said like that, but what they wanted to do was 
exactly the reason that their SDP forbid Unchecked_Conversion.  Whether 
the SDP or the guy writing the improvement request was "right" in the 
context of a particular project was irrelevant to the design of Ada 9X. 
  Ada, as designed, allowed SDPs to easily allow or forbid use of some 
features.  (Right now the best example of this is the SPARK checker that 
forbids exceptions and dynamic allocations.)  The intent was exactly to 
allow projects to "tailor" the subset they used.  (I just ran into 
another CS professor who didn't understand that the Ada 83 "no subsets" 
rule was for validated compilers, not for projects. Sigh.)

Back to the example that started all this.  Either it "makes sense" to 
atomically lock both counters, or it doesn't.  This is a design 
criteria, and will affect how the counters are implemented.  If a later 
change adds this requirement, you may have to change the implementation 
of the counters.  Said like that, it sounds so _obvious_.
-- 

                                           Robert I. Eachus

"The terrorist enemy holds no territory, defends no population, is 
unconstrained by rules of warfare, and respects no law of morality. Such 
an enemy cannot be deterred, contained, appeased or negotiated with. It 
can only be destroyed--and that, ladies and gentlemen, is the business 
at hand."  -- Dick Cheney




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-10 10:49           ` Dmitry A. Kazakov
  2004-04-10 15:35             ` Wojtek Narczynski
@ 2004-04-14 15:57             ` Robert I. Eachus
  2004-04-15  8:04               ` Dmitry A. Kazakov
  1 sibling, 1 reply; 90+ messages in thread
From: Robert I. Eachus @ 2004-04-14 15:57 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> This has nothing to do with abstraction inversion. The problem here is that
> Ada does not have multiple protected actions. Same problem with tasks,
> there cannot be rendezvous with multiple tasks. It is much work to solve
> that. Especially to convince people that prefix notation is inherently bad.

Not quite right.  A decision was made early in the development of Ada 
that a CALLING task can only rendezvous with a single task.  A task can 
accept arbitrarily many calls simultaneously.  You might prefer that the 
rule worked the other way around, but we felt that we had to choose one 
or the other.  Many-to-many rendezvous looked just too messy to contemplate.

AFAIK, the only pattern that uses this feature is the one where you have 
multiple servers and a task that allocates requesting tasks to servers. 
  I have actually used this pattern.

-- 

                                           Robert I. Eachus

"The terrorist enemy holds no territory, defends no population, is 
unconstrained by rules of warfare, and respects no law of morality. Such 
an enemy cannot be deterred, contained, appeased or negotiated with. It 
can only be destroyed--and that, ladies and gentlemen, is the business 
at hand."  -- Dick Cheney




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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-14  8:49                         ` Dmitry A. Kazakov
@ 2004-04-14 16:49                           ` Hyman Rosen
  2004-04-15 10:37                             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 90+ messages in thread
From: Hyman Rosen @ 2004-04-14 16:49 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> But C++ does not allow double as a template parameter.

That's merely an implementation detail; you simply use a
pair of integers to represent a fraction.

> Why? It is no matter. Shifted units represent linear scales:
> x = a * y + b
> The dimension of a and b may have any powers.

No matter? What is the meaning of multiplying degrees Celsius
by degrees Farenheit, or squaring degrees Celsius?

> Because there can be a universal solution with zero-overhead in static case.

Zero overhead in space as well? I assume this is another one of those
cases which will require object tags to live in the classwide pointers
instead of in the objetcs themselves?

> (:-))

Why is my unit output procedure funny?

> Not that is the problem. One can add 1 [mm] and 1 [cm], it is legal. The
> question is in which unit system the arguments are and the result will be.

You need to guide the type of the result, since it could be either.
So it's simpler to forbid the addition of differently scaled units,
and require the user to convert one operand to the type of the other.

Or, given that you're doing it in C++, it's easy to write traits
templates that would represent rules for preferring one scale over
another.

> I do not see how you could add x in meters of SI with y in ft of logarithmic
> scale using specialized templates. To represent scale you will probably
> need some pointer to the scale descriptor in your template.

You represent scale and logness as template parameters. Then you just
need to be able to convert one type to another (and if we're talking
about addition of log-scaled quantities, we have to convert out anyway)
for addition, and to write a specialized multiplication routine that
takes two log-scaled units and adds their values, for example.

I doubt that anyone is going to build such a complicated system of
units, but it could be done in principle.

> I do not see any way of making a GUI or DB interface based on templates.
> Consider a distributed system with should have a communication protocol to
> exchange physical measures. How would you do it using templates?

As I have already said, we are relying on knowing a fixed set of units
within the program. Then the problem is no different than communicating
any other fixed set of record types.

> Consider a large finite element library. If that has to be used for
 > physical values, then the whole library has to be generic.

So?



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-13 10:56                   ` Dmitry A. Kazakov
@ 2004-04-14 21:12                     ` Randy Brukardt
  2004-04-15 10:37                       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 90+ messages in thread
From: Randy Brukardt @ 2004-04-14 21:12 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:c5gh0e$1ba02$3@ID-77047.news.uni-berlin.de...
> Randy Brukardt wrote:
>
> > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> > news:c5b6pt$2pcs4d$2@ID-77047.news.uni-berlin.de...
> > ...
...
> > I don't see how this follows from (1) to (4), though. Each call is just
a
> > dispatching call to a single operation; there is no implementation
> > inheritance.
>
> Yes, but if I could have two dispatching parameters of same protected type
> (no MD involved) in a primitive operation, then a call to it should start
> two protected actions. Same with task entries, (4) should allow something
> like:
>
> task type Foo is ... end Foo;
> entry Double_Rendezvous (X, Y : in out Foo);
>    -- Declared after "end Foo";

This isn't allowed by AI-345; entries can only be declared inside a task
(with the current rules). An interface can have procedures that match
entries (and interface procedure calls can be used in select statements),
but there is no separate existence to entries.

You could declare a procedure like that

procedure Double_Rendezvous (X, Y : in out Foo);

but of course it doesn't have any special semantics.

...
> >> A call to such entry would start multiple protected actions (one per
each protected
> >> object parameter) and multiple rendezvous (one per each task object
> >> parameter). Could we agree that 1-4 is a damn *lot* of work?
> >
> > Not really. *Interfaces* is a lot of work, but presuming that we're
going
> > to have those anyway, adding protected and task support to them is not a
> > significant increment.
>
> I am glad to hear it from you, because of course, you know it better.

I should point out that not everyone agrees with my assessment here. But
it's not clear to me that everyone understands the implementation model for
these, so they may be trying a harder-than-necessary implementation
approach.

                  Randy.






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

* Re: Reprise: 'in out' parameters for functions
  2004-04-14 14:40               ` Robert I. Eachus
@ 2004-04-14 21:20                 ` Randy Brukardt
  0 siblings, 0 replies; 90+ messages in thread
From: Randy Brukardt @ 2004-04-14 21:20 UTC (permalink / raw)


"Robert I. Eachus" <rieachus@comcast.net> wrote in message
news:kf2dnS2GIr_00ODdRVn-hA@comcast.com...
> Randy Brukardt wrote:
>
> > I agree with all of this too. Also not going to happen. See AI-290, also
> > voted "No Action".
>
> On pragma Pure and static expressions, I think that you (Randy) are
> being a little premature.  It may come up again for Ada 1Z.  AI-290 is
> about pragma Pure_Function.

Well, I'm not considering what may or may not happen in Ada 1Z. If it has
the same ground rules as Ada 0Y has, then "not going to happen" is probably
accurate. But, in any case, in a business that moves as fast as the computer
business, the difference between "not sooner than 12-15 years from now" and
"not going to happen" is not particularly interesting.

                   Randy.






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

* Re: Reprise: 'in out' parameters for functions
  2004-04-14 15:57             ` Robert I. Eachus
@ 2004-04-15  8:04               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-15  8:04 UTC (permalink / raw)


Robert I. Eachus wrote:

> Dmitry A. Kazakov wrote:
> 
>> This has nothing to do with abstraction inversion. The problem here is
>> that Ada does not have multiple protected actions. Same problem with
>> tasks, there cannot be rendezvous with multiple tasks. It is much work to
>> solve that. Especially to convince people that prefix notation is
>> inherently bad.
> 
> Not quite right.  A decision was made early in the development of Ada
> that a CALLING task can only rendezvous with a single task.  A task can
> accept arbitrarily many calls simultaneously.  You might prefer that the
> rule worked the other way around, but we felt that we had to choose one
> or the other.  Many-to-many rendezvous looked just too messy to
> contemplate.

Right, I do not know how difficult it would be to implement, but definitely,
it would make statical analysis more complicated. So it is not clear
whether this feature would give any real advantage.

> AFAIK, the only pattern that uses this feature is the one where you have
> multiple servers and a task that allocates requesting tasks to servers.
>   I have actually used this pattern.

Thank you for the example, because I never needed multiple rendezvous.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-14 15:03                         ` Wojtek Narczynski
@ 2004-04-15 10:37                           ` Dmitry A. Kazakov
  2004-04-16  0:29                             ` Wojtek Narczynski
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-15 10:37 UTC (permalink / raw)


Wojtek Narczynski wrote:

>> I did not disagree with your definition. I did with your statement that
>> Ada's protected objects are wrong way. They might have problems, though.
>> But it appeared, as you treating them as completely wrong.
> 
> "Wrong" seems to be one of your favourite words. I merely said that
> Ada concurrency features are not expressive enough not to require
> abstraction inversion in many cases.

Sorry, but I still do not get your point. Either Ada features are 1) beyond
any help; 2) OK, but has to be impoved in some definite way; 3) Excellent.
It seems that you do not agree with (3). So either (1) or (2) remain. Which
one?

>>> Checking physical units statically would be helpful for high
> integrity
>>> software. I don't see any practical use for runtime unit checks.
>  
>> Only because I see no smiley... How would you implement:
>> 
>> procedure Put (Stream : File, Value : Measurement);
>> procedure Get (Stream : File, Value : out Measurement);
>> 
>> For example, a requirement of one of our customer was to have a button in
>> his MMI to switch between European and American units in all visual
>> elements and printouts. Now go, figure out, how would you solve that
>> using templates.
> 
> Huhm, we are talking about _checks_, then we are suddenly talking
> about _conversions_.

I gave you an example of a *real* application requiring units (and units
checks, because surely in any place where the system expects, say, a
velocity, the operator may give it in any compatible unit: knot, km/h, m/s,
mph, whatsoever, but not in kPa. So units are indeed checked.)

> But even for conversions, even though they are
> most certainly useful in many cases at runtime, the idea to hardcode
> the external representation of values with units into the compiler and
> runtime, is unfortunate.

I do not follow you here. My example shows that static *only* checks are
insufficient. Period. This does not imply that it is impossible to create a
unit system which would be statically checkable. I already mentioned in my
previous post that Ada designers managed to do a similar job with the type
String. Carefully observe how Ada deals with statically constrained String
subtypes. In my view it is quite possible to deal this way with dimensioned
values too.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-14 21:12                     ` Randy Brukardt
@ 2004-04-15 10:37                       ` Dmitry A. Kazakov
  0 siblings, 0 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-15 10:37 UTC (permalink / raw)


Randy Brukardt wrote:

> An interface can have procedures that match
> entries (and interface procedure calls can be used in select statements),
> but there is no separate existence to entries.

I see, it is a one-way road. (:-))

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions)
  2004-04-14 16:49                           ` Hyman Rosen
@ 2004-04-15 10:37                             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-15 10:37 UTC (permalink / raw)


Hyman Rosen wrote:

> Dmitry A. Kazakov wrote:
>> But C++ does not allow double as a template parameter.
> 
> That's merely an implementation detail; you simply use a
> pair of integers to represent a fraction.

Ooch.

>> Why? It is no matter. Shifted units represent linear scales:
>> x = a * y + b
>> The dimension of a and b may have any powers.
> 
> No matter? What is the meaning of multiplying degrees Celsius
> by degrees Farenheit,

It is ambigous. But you can multiply Kelvin by Kelvin. For example, heat
flux has the dimension:

m**2 * kg / K**3

> or squaring degrees Celsius?

>> Because there can be a universal solution with zero-overhead in static
>> case.
> 
> Zero overhead in space as well? I assume this is another one of those
> cases which will require object tags to live in the classwide pointers
> instead of in the objetcs themselves?

Right. The idea is to have the powers as a discriminant and unit arithmetics
as pure routines. When the discriminant (unit) is statically known, it is
removed and we have a full equivalent of the template solution. When it is
unknown, we have run-time checks with space penalty. I belive it is a
doable approch, which has an additional advantage, that this mechanism
could be made available for all user types.

>> (:-))
> 
> Why is my unit output procedure funny?

It is still static and may no input counterpart.

>> Not that is the problem. One can add 1 [mm] and 1 [cm], it is legal. The
>> question is in which unit system the arguments are and the result will
>> be.
> 
> You need to guide the type of the result, since it could be either.
> So it's simpler to forbid the addition of differently scaled units,
> and require the user to convert one operand to the type of the other.

This does not solve the problem. These conversions either explicit or
implicit has to be done and thus checked. We have a geometrically exploding
number of cross conversions.
 
> Or, given that you're doing it in C++, it's easy to write traits
> templates that would represent rules for preferring one scale over
> another.

Too uncontrollable. The choice depends on the target value, so one cannot
say if lightyear is better than micrometer.

>> I do not see how you could add x in meters of SI with y in ft of
>> logarithmic scale using specialized templates. To represent scale you
>> will probably need some pointer to the scale descriptor in your template.
> 
> You represent scale and logness as template parameters. Then you just
> need to be able to convert one type to another (and if we're talking
> about addition of log-scaled quantities, we have to convert out anyway)
> for addition, and to write a specialized multiplication routine that
> takes two log-scaled units and adds their values, for example.

You have to do it for each of seven powers, representing each parameter by a
number of integers. I am afraid that the list of template arguments will be
longer than the source code. To have enough RAM to compile it, you would
need to made sand of all beaches into memory chips. And I am not sure if
the compiler will finish before the Entropic Death (:-))

> I doubt that anyone is going to build such a complicated system of
> units, but it could be done in principle.

Yes, it is Turing complete. (:-))

>> I do not see any way of making a GUI or DB interface based on templates.
>> Consider a distributed system with should have a communication protocol
>> to exchange physical measures. How would you do it using templates?
> 
> As I have already said, we are relying on knowing a fixed set of units
> within the program. Then the problem is no different than communicating
> any other fixed set of record types.

The problem is that you cannot have one piece of code dealing with all units
(though from a fixed set). You probably will be able to create a template
for this code, but the number of variants will be far greater than any
computer may hold. You need to instantiate all of them, because you do not
know which of them will be used at tun time.

And after all, who will be able to maintain this code? Finding an error in
C++ template instantiations is a work requiring a lot of experience, much
patience and great luck. And we want to give it engineers, who else needs
units so much? Even in Ada dealing with generics imposes much more
difficulties for a programmer than regular code. The price is to high.

>> Consider a large finite element library. If that has to be used for
>  > physical values, then the whole library has to be generic.
> 
> So?

Absolutely unrealistic.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Expressing physical units
  2004-04-13  9:53             ` Wojtek Narczynski
@ 2004-04-15 21:27               ` Jacob Sparre Andersen
  2004-04-16 11:40                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 90+ messages in thread
From: Jacob Sparre Andersen @ 2004-04-15 21:27 UTC (permalink / raw)


Wojtek Narczynski wrote:

> Macks is not Ada, okay?

I am tempted to say that it is, but no, it is a tool that helps me
write my Ada code for handling physical units.

> But I will take a closer look at how it works.

Do that.  It still has some quirks, but it is a useful tool anyway.
One thing you have too be aware of is that it can generate code
according to more than one principle for handling physical units (at
least in the version I have).

Jacob
-- 
"Then, after a second or so, nothing continued to happen."



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-15 10:37                           ` Dmitry A. Kazakov
@ 2004-04-16  0:29                             ` Wojtek Narczynski
  2004-04-16 11:36                               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-16  0:29 UTC (permalink / raw)


Hello,

> Sorry, but I still do not get your point. Either Ada features are 1) beyond
> any help; 2) OK, but has to be impoved in some definite way; 3) Excellent.
> It seems that you do not agree with (3). So either (1) or (2) remain. Which
> one?

Depends on the application. For highly concurrent data structures that
would be 1, for tutorials 3. For many applications they are probably
okay. I am talking about concurrency features only now, but other
parts of the language also have their problems. Still, with all the
problems, Ada is  overall the best procedural language I've seen.

---
 
> I gave you an example of a *real* application requiring units (and units
> checks, because surely in any place where the system expects, say, a
> velocity, the operator may give it in any compatible unit: knot, km/h, m/s,
> mph, whatsoever, but not in kPa. So units are indeed checked.)

You could make it unable to enter a wrong unit in the interface. So
this would be ensuring that 'Unit_Error' cannot be raised, rather than
catching and handling it. But it is not always possible, for example
when reading from an untrusted file, so you are right.

> I already mentioned in my  previous post that Ada designers managed to do a 
> similar job with the type String. Carefully observe how Ada deals with 
> statically constrained String subtypes. In my view it is quite possible to 
> deal this way with dimensioned values too.

I've studied your code on units, I admit I should have done that
before engaging in discussion about units with you.

Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-14 15:46           ` Robert I. Eachus
@ 2004-04-16  1:52             ` Wojtek Narczynski
  2004-04-16  5:40               ` Robert I. Eachus
  0 siblings, 1 reply; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-16  1:52 UTC (permalink / raw)


>> Or the simplest possible: two protected counters, try to get the
>> sum atomically.
 
> Since this is trivial, I can only assume that you have two protected 
> counters with no support for external locking in mind.

I had in mind implementing it without the need to resort to
abstraction inversion, which I understand as -for example-
implementing semaphores over protected objects, which are implemented
over semaphores.

> Actually, you can even do that, by having one counter have a Sum operation 
> that calls the other. However, this whole subject is probably silly.

Yes, this is silly because I oversimplifed the problem.

The original problem I run into was how to implement a highly
concurrent, space and time efficient list, tree, and finally lock
manager.

And before that, I wanted to grab a ready implementation of this
(list, tree) from some library, but I could not find such a thing...

> Reminds me of a lot of improvement requests for Ada 9X.  "We want to do 
> such and such."
> 
> "Well, here is a simple example of how to do it in current Ada."
> 
> "Oh, but our software development plan doesn't allow us to use 
> Unchecked_Conversion."

Yes, I should probably have dropped protected type in favor of raw
semaphores.

Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-16  1:52             ` Wojtek Narczynski
@ 2004-04-16  5:40               ` Robert I. Eachus
  2004-04-16 11:38                 ` Wojtek Narczynski
  0 siblings, 1 reply; 90+ messages in thread
From: Robert I. Eachus @ 2004-04-16  5:40 UTC (permalink / raw)


Wojtek Narczynski wrote:

> I had in mind implementing it without the need to resort to
> abstraction inversion, which I understand as -for example-
> implementing semaphores over protected objects, which are implemented
> over semaphores.

Protected objects _may_ be implemented using semaphores, or mutexes, or 
counters, or any viable atomic action.  But when you are programming in 
Ada, you have to take the tasking model, complex as it seems, as the 
fundamental primitive for concurrency.  Protected objects were added to 
Ada 9X to eliminate some of the baggage that most implementations of Ada 
tasking carried.  And to some extent they did just that.  But if I need 
fast semaphores, I use a semaphore abstraction, then I try various 
implementations of the abstraction to find one which has the performance 
I need.  If implementing a semaphore portably as a protected object 
works?  Done.

> Yes, I should probably have dropped protected type in favor of raw
> semaphores.

Protected objects are a very useful model for a lot of jobs that require 
management of concurrency.  But it is a characteristic of protected 
objects that they manage _their_own_ concurrency, and nothing else.  As 
long as that model fits what you are doing, great protected objects have 
great advantages over other techniques, such as semaphores.

But there are two important points.  First you _must_ as part of your 
analysis of the problem domain identify the objects that need to be 
managed.  For lists and trees, two of the examples you mentioned, what 
usually needs to be managed is the list, or the tree:

protected type List is
   procedure Append(E: in Element);
   procedure Prepend(E: in Element);
   ...
   function Is_Empty return Boolean;
   function Length return Natural;
private
   ...
end List;

Should you expect to find a ready made implementation that meets your 
needs?  Possibly.  But you almost certainly won't find it by looking for 
libraries of protected objects.  The usual in Ada is to provide a 
generic package abstraction where the protected object is hidden from 
the user's sight.  This allows it to "reuse" the interface of a List 
that doesn't need protection from concurrent access.  In fact, one of 
the changes in Ada 95 was intended to make it easier to 'hide' such a 
protected type in the body of a (generic) package.

To go back to the example that sparked the discussion, it is not that 
difficult to create a protected type which protects an array of 
counters.  It then seems natural to have both a set of atomic operations 
on a single counter and on a set of counters:

type Index is (<>);
generic package Counters is

    type Set is array (Index) of Boolean;

    type Count_Array is (Index range <>) of Integer;

    protected type Counters is
       procedure Reset(I: Index);
       procedure Reset(S: Set);
       procedure Reset; -- Zero all counters.
       function Count(I: Index) return Integer;
       function Count(S: Set) return Count_Array;
       function Count return Count_Array;
       --return a snapshot of all counts
    private
       ...
    end Counters;

Now you may think that this is an abstraction inversion, but I don't. 
That is really a comment on thinking Ada.  Even with Ada 83, it was 
_hard_ to correctly identify the 'right' objects to make the rest of the 
project easy, and Ada 95 has made those choices much harder.  But the 
way it has done that is by making the object calculus much more powerful.

I used to have a fully worked out example that demonstrated the issue. 
It was a simulation of a barber shop, with multiple chairs and barbers, 
customers who decided to return later if there were too many other 
customers waiting, and so on.  But none of that was the point of the 
example.  There was a simple elegant object-oriented solution.  The 
insight you needed to find it though, was that the key objects were the 
haircuts!

You could also probably come up with just as clean a model if you made 
the customers the key objects, but somehow _trying_ to do that leads you 
astray.  If a parent comes into the barber shop with a child, who is the 
customer?  Much easier to get it right, if you are thinking that a 
father comes into the barber shop to get _haircuts_ for both himself and 
his son, or only his son, or whatever.

There are lots of ways to identify the potential objects in a program. 
Grady Booch's method of describing the problem space and underlining all 
the nouns is probably as good as any.  But that is where the hard work 
begins.  As in the barber shop example, there is some minimal set of 
objects that need to be modelled, or perhaps a better way to say that is 
that there is a minimal set of expensive objects that does the job. 
What makes objects expensive? It can be storage space, allocation and 
deallocation, active state, or some combination of the above.  But you 
often don't know what cost function for the project will be at that 
stage of the analysis.  You have to try strawmen, see which project 
constraints bind hardest, then start looking for opportunties to trade 
one resource for another.  Sometimes, as in the barber shop example, 
there will be one elegant model which minimizes the cost in all 
dimensions.  Other times, the engineering tradeoffs need to be decided 
before you can actually start coding.

-- 

                                           Robert I. Eachus

"The terrorist enemy holds no territory, defends no population, is 
unconstrained by rules of warfare, and respects no law of morality. Such 
an enemy cannot be deterred, contained, appeased or negotiated with. It 
can only be destroyed--and that, ladies and gentlemen, is the business 
at hand."  -- Dick Cheney




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-16  0:29                             ` Wojtek Narczynski
@ 2004-04-16 11:36                               ` Dmitry A. Kazakov
  2004-04-16 19:25                                 ` Wojtek Narczynski
  0 siblings, 1 reply; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-16 11:36 UTC (permalink / raw)


Wojtek Narczynski wrote:

>> Sorry, but I still do not get your point. Either Ada features are 1)
>> beyond any help; 2) OK, but has to be impoved in some definite way; 3)
>> Excellent. It seems that you do not agree with (3). So either (1) or (2)
>> remain. Which one?
> 
> Depends on the application. For highly concurrent data structures that
> would be 1, for tutorials 3.

Does it mean that 1.a) there is a better approach, or that 1.b) parallel
applications are hard to develop? I would definitely disagree with the
first and agree with the second.

> For many applications they are probably
> okay. I am talking about concurrency features only now, but other
> parts of the language also have their problems.

Any language has problems.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-16  5:40               ` Robert I. Eachus
@ 2004-04-16 11:38                 ` Wojtek Narczynski
  2004-04-16 16:30                   ` Robert I. Eachus
                                     ` (2 more replies)
  0 siblings, 3 replies; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-16 11:38 UTC (permalink / raw)


Robert,

First of all, thanks for writing me an essay. One day you might think
of gathering all your c.l.a posts into a book. I would definitely buy
a copy.

But let me push it a bit more.

> But there are two important points. First you _must_ as part of your 
> analysis of the problem domain identify the objects that need to be 
> managed. 

Analysis for generic data structures has been done decades ago. I'd
prefer to use something readily available and not redo the analysis at
this level.

But let's grant that, as a result of throughout analysis, you conclude
that you need a list that is sorted, space efficient, time efficient,
updateable from many tasks at the same time. Any hint on how to
implement this?

> protected type List is
>    procedure Append(E: in Element);
>    procedure Prepend(E: in Element);
>    ...
>    function Is_Empty return Boolean;
>    function Length return Natural;
> private
>    ...
> end List;

If you do this, only one task / thread will be able to update the data
structure.

> Should you expect to find a ready made implementation that meets your 
> needs?  Possibly.  But you almost certainly won't find it by looking for 
> libraries of protected objects. 

I found no examples of data structures with lock granularity lower
than the whole data structure.

Regards,
Wojtek



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

* Re: Expressing physical units
  2004-04-15 21:27               ` Expressing physical units Jacob Sparre Andersen
@ 2004-04-16 11:40                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 90+ messages in thread
From: Dmitry A. Kazakov @ 2004-04-16 11:40 UTC (permalink / raw)


Jacob Sparre Andersen wrote:

> Wojtek Narczynski wrote:
> 
>> Macks is not Ada, okay?
> 
> I am tempted to say that it is, but no, it is a tool that helps me
> write my Ada code for handling physical units.

I would say that Macks is as Ada as generics are, or as templates are C++.
In my view all of them constitute a kind of meta language.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-16 11:38                 ` Wojtek Narczynski
@ 2004-04-16 16:30                   ` Robert I. Eachus
  2004-04-16 18:38                   ` Randy Brukardt
  2004-04-16 19:28                   ` Wojtek Narczynski
  2 siblings, 0 replies; 90+ messages in thread
From: Robert I. Eachus @ 2004-04-16 16:30 UTC (permalink / raw)


Wojtek Narczynski wrote:

> I found no examples of data structures with lock granularity lower
> than the whole data structure.

That is what I would expect you would find.  Why would you expect 
anything different?  For a list you might be able to prepend and append 
at the same time, but the more complex organization just doesn't seem 
worth it.

For trees you can have one lock per object, and insertions, for example, 
would only hold the locks on those nodes needed for the insertion.  From 
experience it is _possible_ but the performance of one lock per data 
structure instance performs much better.  (Look at it this way.  If you 
have one lock per node, then every query needs to start by locking the 
root node, so your transactions are going to be serialized anyway.  As 
long as the whole tree _structure_ is in memory, doing the tree walk 
inside that one lock is more efficient than having to acquire and 
release a dozen locks, even though the first lock will serialize everything.

If you have a situation where you need to lock a node for the duration 
of a transaction, the best choice--again from experience--is to have one 
lock for the tree structure, and one lock for the _contents_ of each 
node.  That way you can have many transactions walking the tree at the 
same time (many readers) but the time consuming part of the transaction, 
which may require waiting for human interaction has a write lock on the 
content, not on the tree.  Deleting or inserting a new node does require 
a write lock on the tree as a whole, but for AVL trees or B-trees the 
difference between that and locking 'just' the part of the tree which is 
potentially changing just isn't worth the extra overhead.

To sum up, in theory there is no difference between theory and practice, 
but in practice there is.

Oh one last observation, it may seem that to do an update of a tree node 
only requires a lock on the node contents, but this is not true in all 
cases.  If the update of the contents changes the key, you have to 
delete the entry from the tree and reinsert it.  This means you want to 
choose a key which is not often changed.  (Just one reason why so many 
things are keyed by SSAN.)


-- 

                                           Robert I. Eachus

"The terrorist enemy holds no territory, defends no population, is 
unconstrained by rules of warfare, and respects no law of morality. Such 
an enemy cannot be deterred, contained, appeased or negotiated with. It 
can only be destroyed--and that, ladies and gentlemen, is the business 
at hand."  -- Dick Cheney




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-16 11:38                 ` Wojtek Narczynski
  2004-04-16 16:30                   ` Robert I. Eachus
@ 2004-04-16 18:38                   ` Randy Brukardt
  2004-04-16 22:15                     ` Wojtek Narczynski
  2004-04-16 19:28                   ` Wojtek Narczynski
  2 siblings, 1 reply; 90+ messages in thread
From: Randy Brukardt @ 2004-04-16 18:38 UTC (permalink / raw)


"Wojtek Narczynski" <wojtek@power.com.pl> wrote in message
news:5ad0dd8a.0404160338.5a1c9116@posting.google.com...
...
> I found no examples of data structures with lock granularity lower
> than the whole data structure.

That's because it would be hard to avoid deadlock in such data structures.
(And, as Robert points out, the cost of grabbing a lot of locks would be
very high.)

The usual way of avoiding deadlock is the use the onion-skin model of
locking. But that would serialize the data structure anyway, so there
wouldn't be much point in separate locks.

To see the problem, consider a tree struction. You'd have to lock many nodes
if an insertion caused a rebalancing. If a second task tried to do a nearby
insertion at the same time, it also could lock a number nodes. It would be
quite likely for the second task to lock the nodes that it is going to
insert into, then the first task try to lock the same nodes to do a
rebalancing. So it would have to wait. Then the second task would discover
that it, too needs to do a rebalancing - but it can't, because the first
task already has locked some of the nodes that it needs to change for the
rebalancing. Classic deadlock.

To avoid this situation, you have to lock the whole data structure. The only
place where you could get parallel operation is in modifying the elements
once inserted. (And in a library like Ada.Containers, that's done updating a
copy of the element, then calling the library to replace the previous
element.)

                  Randy.







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

* Re: Reprise: 'in out' parameters for functions
  2004-04-16 11:36                               ` Dmitry A. Kazakov
@ 2004-04-16 19:25                                 ` Wojtek Narczynski
  0 siblings, 0 replies; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-16 19:25 UTC (permalink / raw)


Dimitry,

> Does it mean that 1.a) there is a better approach, or that 1.b) parallel
> applications are hard to develop? I would definitely disagree with the
> first and agree with the second.

Clearly parallel applications extremely hard to develop.

Regarding better approach (than protected for highly concurrent data
structures). It depends on what "better" means in a given context. For
example, there are more time and space efficient, allowing higher
concurrency, approaches.

Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-16 11:38                 ` Wojtek Narczynski
  2004-04-16 16:30                   ` Robert I. Eachus
  2004-04-16 18:38                   ` Randy Brukardt
@ 2004-04-16 19:28                   ` Wojtek Narczynski
  2 siblings, 0 replies; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-16 19:28 UTC (permalink / raw)


Hello,

> I found no examples of data structures with lock granularity lower
> than the whole data structure.

...lock granularity higher than...

Sorry,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-16 18:38                   ` Randy Brukardt
@ 2004-04-16 22:15                     ` Wojtek Narczynski
  2004-04-17  1:20                       ` Robert I. Eachus
  0 siblings, 1 reply; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-16 22:15 UTC (permalink / raw)


Randy,

> That's because it would be hard to avoid deadlock in such data structures.

Yes, it is hard to avoid deadlocks.

> The usual way of avoiding deadlock is the use the onion-skin model of
> locking. 

With acyclic strucutres you do "crabbing" to avoid deadlocks.

> To see the problem, consider a tree struction. You'd have to lock many nodes
> if an insertion caused a rebalancing. If a second task tried to do a nearby
> insertion at the same time, it also could lock a number nodes. It would be
> quite likely for the second task to lock the nodes that it is going to
> insert into, then the first task try to lock the same nodes to do a
> rebalancing. So it would have to wait. Then the second task would discover
> that it, too needs to do a rebalancing - but it can't, because the first
> task already has locked some of the nodes that it needs to change for the
> rebalancing. Classic deadlock. To avoid this situation, you have to lock the
> whole data structure. 

This is not easy but solveable. For example ADABAS (and forks)
relational database is organized as one large B* tree. It can be
edited concurrently, it rebalances, and does not deadlock.

One more example: Java heap, millions of objects, 64 CPUs, thousands
of threads. Would you like to have one lock for the whole data
strucutre?

Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-16 22:15                     ` Wojtek Narczynski
@ 2004-04-17  1:20                       ` Robert I. Eachus
  2004-04-17 11:42                         ` Wojtek Narczynski
  0 siblings, 1 reply; 90+ messages in thread
From: Robert I. Eachus @ 2004-04-17  1:20 UTC (permalink / raw)




Wojtek Narczynski wrote:

> This is not easy but solveable. For example ADABAS (and forks)
> relational database is organized as one large B* tree. It can be
> edited concurrently, it rebalances, and does not deadlock.
> 
> One more example: Java heap, millions of objects, 64 CPUs, thousands
> of threads. Would you like to have one lock for the whole data
> strucutre?

You are missing the point.  The answer is no, one lock per storage pool. 
  How many storage pools do you have?  At least one per CPU, more 
usually two or three due to different storage management protocols.  But 
the major insight is that you either update a copy of an object and then 
  swap it in atomically as Randy said, or (my preference) the lock for 
the data structure controls the data structure and a separate per object 
lock controls the object updates.  (Except changing index keys, which 
has to be done Randy's way.)

The simplest data structure locking protocol is usually by far the most 
efficient.  Spending a dozen times as many CPU cycles on lock management 
to double or triple the effective concurrency is a joke, and you will 
find that holding complex schemes to only a dozen times as long is 
difficult.  Factor in memory caches, and anything else is crazy.

What is important, in real cases, is memory management.  Having any part 
of a data structure paged to disk can kill performance.  (The data 
structure now, not the actual data.)  This is why I tend to implement 
the tree or whatever with a pointer (excuse me access value) designating 
  the data.  That way the next data structure entry you need will be in 
main memory, and is much more likely to be in cache.

(If you also figure from this that I am one of those people who designs 
large objects and not that many of them, you are right.  Complex data 
dictionaries are all right for the theoretical part of design, but when 
it comes to practice, you want to merge data nodes to the maximum extent 
possible.)

-- 

                                           Robert I. Eachus

"The terrorist enemy holds no territory, defends no population, is 
unconstrained by rules of warfare, and respects no law of morality. Such 
an enemy cannot be deterred, contained, appeased or negotiated with. It 
can only be destroyed--and that, ladies and gentlemen, is the business 
at hand."  -- Dick Cheney




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-17  1:20                       ` Robert I. Eachus
@ 2004-04-17 11:42                         ` Wojtek Narczynski
  2004-04-17 14:14                           ` Robert I. Eachus
  0 siblings, 1 reply; 90+ messages in thread
From: Wojtek Narczynski @ 2004-04-17 11:42 UTC (permalink / raw)


Robert,

> What is important, in real cases, is memory management.  Having any part 
> of a data structure paged to disk can kill performance. (The data 
> structure now, not the actual data.)

Another problem of this kind is that the lock owner thread can get
preempted by the operating system. This is more frequent, but less
devastating than a page fault.

> (Complex data dictionaries are all right for the theoretical part of design,
> but when it comes to practice, you want to merge data nodes to the maximum
> extent possible.)

Okay, practitioners speaking, so I will just listen. Should I ask for
a refunt for "Transaction Processing: Concept and Techniques" by
J.Gray & A. Reuter? :-)


Regards,
Wojtek



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

* Re: Reprise: 'in out' parameters for functions
  2004-04-17 11:42                         ` Wojtek Narczynski
@ 2004-04-17 14:14                           ` Robert I. Eachus
  0 siblings, 0 replies; 90+ messages in thread
From: Robert I. Eachus @ 2004-04-17 14:14 UTC (permalink / raw)


Wojtek Narczynski wrote:

> Another problem of this kind is that the lock owner thread can get
> preempted by the operating system. This is more frequent, but less
> devastating than a page fault.

There are "tricks" to minimize this.  Even if I am programming at system 
independent level, I try to insure that all pages that may be needed 
inside a lock have been referenced outside the lock first.  In a formal 
sense, this won't improve things, but in practice it can make the 
difference between good performance and bad.

The best of all possible worlds is a compiler that wraps protected 
actions in an interrupt-deferred region.  Like all real-time features, 
this is a two-edged sword, but one you have to use in some cases.

> Okay, practitioners speaking, so I will just listen. Should I ask for
> a refunt for "Transaction Processing: Concept and Techniques" by
> J.Gray & A. Reuter? :-)

Theory is important, so is practice.  Without the theory you don't know 
what is and isn't correct in a formal sense.  But in real-time 
programming, too late is just as bad as any other error, and it is an 
emergent property of the whole system.

It is very frustrating to design a race free and deadlock free system, 
then find that to meet the performance requirements you have to violate 
some of the assumptions necessary to make the system deadlock free. 
Yes, you can often go "back to the drawing board" and come up with a 
more complex solution that works and meets the requirements.  But far 
more often, you end up with a solution which is only deadlock free 
because it occasionally aborts lower priority transactions.

-- 

                                           Robert I. Eachus

"The terrorist enemy holds no territory, defends no population, is 
unconstrained by rules of warfare, and respects no law of morality. Such 
an enemy cannot be deterred, contained, appeased or negotiated with. It 
can only be destroyed--and that, ladies and gentlemen, is the business 
at hand."  -- Dick Cheney




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

* Re: Reprise: 'in out' parameters for functions
  2004-04-08 20:32   ` Randy Brukardt
@ 2005-01-12 15:15     ` okellogg
  2005-01-12 20:14       ` Randy Brukardt
  0 siblings, 1 reply; 90+ messages in thread
From: okellogg @ 2005-01-12 15:15 UTC (permalink / raw)


On Apr 8 2004, 1:32 pm, Randy Brukardt wrote:
>
> "Georg Bauhaus" <sb463ba@l1-hrz.uni-duisburg.de> wrote in message
> news:c546fd$lkb$3@a1-hrz.uni-duisburg.de...
> > Stephen Leake <stephen_leake@acm.org> wrote:
> >
> > :   Token       : in out Token_List.List_Iterator)
> > Is
> >     Token       : access Token_List.List_Iterator)
> > not an option?
>
> It's rarely an option, because it (a) forces a particular declaration
> ('aliased') on users that have no need to know and (b) makes a messy
call
> with the need to use '[Unchecked_]Access in every call.
>

This triggers a different question:

With Ada2005's support for object-dot-operation notation, will it be
possible to write the following?

package test is
type obj_t is tagged private;
function f (self : access obj_t) return integer;
-- need 'access' mode here because f modifies self
private
-- ...
end test;

with test;
procedure main is
object : test.obj_t;
retval : integer;
begin
retval := object.f;
end main;


My point here is whether main.object need be declared aliased or not.
I would much prefer if it needn't be.

Thanks,

Oliver M. Kellogg




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

* Re: Reprise: 'in out' parameters for functions
  2005-01-12 15:15     ` okellogg
@ 2005-01-12 20:14       ` Randy Brukardt
  0 siblings, 0 replies; 90+ messages in thread
From: Randy Brukardt @ 2005-01-12 20:14 UTC (permalink / raw)



"okellogg" <okellogg@freenet.de> wrote in message
news:1105542923.381339.189580@z14g2000cwz.googlegroups.com...
...
> This triggers a different question:
>
> With Ada2005's support for object-dot-operation notation, will it be
> possible to write the following?
>
> package test is
> type obj_t is tagged private;
> function f (self : access obj_t) return integer;
> -- need 'access' mode here because f modifies self
> private
> -- ...
> end test;
>
> with test;
> procedure main is
> object : test.obj_t;
> retval : integer;
> begin
> retval := object.f;
> end main;
>
>
> My point here is whether main.object need be declared aliased or not.
> I would much prefer if it needn't be.

I agree with you, but I lost that discussion. It was felt that it was
important that this notation was just syntactic sugar, and didn't have any
effect on semantics.

I would have prefered that "aliased" be not required for tagged objects at
all, given that they are always by reference anyway (and you can always take
'access of them once they're passed as a parameter), so there isn't much
point to the declaration. But some people thought that "aliased" was useful
for readers. I didn't press the point...

                            Randy.







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

end of thread, other threads:[~2005-01-12 20:14 UTC | newest]

Thread overview: 90+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <u4qrv5hwr.fsf@acm.org>
2004-04-08 17:19 ` Reprise: 'in out' parameters for functions Alexander E. Kopilovich
     [not found] ` <bRecOT0TxF@VB1162.spb.edu>
2004-04-08 23:46   ` Stephen Leake
2004-04-09  9:23     ` Florian Weimer
2004-04-09 10:04       ` Dmitry A. Kazakov
2004-04-09 11:23         ` Martin Krischik
2004-04-09 12:44           ` Dmitry A. Kazakov
2004-04-09 22:48             ` Randy Brukardt
2004-04-14 14:40               ` Robert I. Eachus
2004-04-14 21:20                 ` Randy Brukardt
2004-04-09 22:47         ` Florian Weimer
2004-04-10 10:49           ` Dmitry A. Kazakov
2004-04-10 11:11             ` Florian Weimer
2004-04-10 13:26               ` Dmitry A. Kazakov
2004-04-10 20:50                 ` Georg Bauhaus
2004-04-11 10:31                   ` Dmitry A. Kazakov
2004-04-09 11:27       ` Stephen Leake
2004-04-09 22:46       ` Randy Brukardt
2004-04-09 13:12     ` Wojtek Narczynski
2004-04-09 15:48       ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen
2004-04-10 13:07         ` Wojtek Narczynski
2004-04-10 13:52           ` Jacob Sparre Andersen
2004-04-11  2:45             ` Hyman Rosen
2004-04-11 10:14               ` Expressing physical units Jacob Sparre Andersen
2004-04-11 16:05                 ` Hyman Rosen
2004-04-12  6:58               ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Russ
2004-04-12 10:29                 ` Dmitry A. Kazakov
2004-04-13  6:52                   ` Russ
2004-04-13 10:55                     ` Dmitry A. Kazakov
2004-04-14  4:50                       ` Hyman Rosen
2004-04-14  8:49                         ` Dmitry A. Kazakov
2004-04-14 16:49                           ` Hyman Rosen
2004-04-15 10:37                             ` Dmitry A. Kazakov
2004-04-14  7:10                       ` Russ
2004-04-14  8:53                         ` tmoran
2004-04-14  9:01                           ` Vinzent 'Gadget' Hoefler
2004-04-14  9:21                         ` Dmitry A. Kazakov
2004-04-13  9:53             ` Wojtek Narczynski
2004-04-15 21:27               ` Expressing physical units Jacob Sparre Andersen
2004-04-16 11:40                 ` Dmitry A. Kazakov
2004-04-09 16:17       ` Reprise: 'in out' parameters for functions Georg Bauhaus
2004-04-10  2:28         ` Wojtek Narczynski
2004-04-10  9:46           ` Georg Bauhaus
2004-04-10 10:49           ` Dmitry A. Kazakov
2004-04-10 15:35             ` Wojtek Narczynski
2004-04-10 21:01               ` Georg Bauhaus
2004-04-10 21:16               ` Georg Bauhaus
2004-04-11 13:20                 ` exception parameters Stephen Leake
2004-04-12 10:29                   ` Dmitry A. Kazakov
2004-04-13  0:58                     ` Stephen Leake
2004-04-13  1:30                       ` Randy Brukardt
2004-04-13  8:04                   ` Jean-Pierre Rosen
2004-04-11 10:31               ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov
2004-04-12 22:02                 ` Randy Brukardt
2004-04-13 10:56                   ` Dmitry A. Kazakov
2004-04-14 21:12                     ` Randy Brukardt
2004-04-15 10:37                       ` Dmitry A. Kazakov
2004-04-13  9:30                 ` Wojtek Narczynski
2004-04-13 12:00                   ` Dmitry A. Kazakov
2004-04-13 22:41                     ` Wojtek Narczynski
2004-04-14  8:49                       ` Dmitry A. Kazakov
2004-04-14 15:03                         ` Wojtek Narczynski
2004-04-15 10:37                           ` Dmitry A. Kazakov
2004-04-16  0:29                             ` Wojtek Narczynski
2004-04-16 11:36                               ` Dmitry A. Kazakov
2004-04-16 19:25                                 ` Wojtek Narczynski
2004-04-14 15:57             ` Robert I. Eachus
2004-04-15  8:04               ` Dmitry A. Kazakov
2004-04-10 12:32           ` Wojtek Narczynski
2004-04-14 15:46           ` Robert I. Eachus
2004-04-16  1:52             ` Wojtek Narczynski
2004-04-16  5:40               ` Robert I. Eachus
2004-04-16 11:38                 ` Wojtek Narczynski
2004-04-16 16:30                   ` Robert I. Eachus
2004-04-16 18:38                   ` Randy Brukardt
2004-04-16 22:15                     ` Wojtek Narczynski
2004-04-17  1:20                       ` Robert I. Eachus
2004-04-17 11:42                         ` Wojtek Narczynski
2004-04-17 14:14                           ` Robert I. Eachus
2004-04-16 19:28                   ` Wojtek Narczynski
2004-04-09 17:09       ` Pascal Obry
2004-04-10  2:37         ` Wojtek Narczynski
     [not found] <u8yh75y33.fsf@acm.org>
2004-04-07 23:54 ` Alexander E. Kopilovich
     [not found] ` <WLZI9T09aE@VB1162.spb.edu>
2004-04-08  2:21   ` Stephen Leake
2004-04-07 20:31 Stephen Leake
2004-04-08 18:42 ` Georg Bauhaus
2004-04-08 20:32   ` Randy Brukardt
2005-01-12 15:15     ` okellogg
2005-01-12 20:14       ` Randy Brukardt
2004-04-08 23:48   ` Stephen Leake
2004-04-13 14:45 ` Robert I. Eachus

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