comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Mutable parameter of a function (long ago was: Re: What evil would happen?)
Date: Sat, 03 Jan 2004 12:18:10 +0100
Date: 2004-01-03T12:18:10+01:00	[thread overview]
Message-ID: <bt681k$3klk4$1@ID-77047.news.uni-berlin.de> (raw)
In-Reply-To: JrWdnTPKPZHVvGuiRVn-uA@comcast.com

Robert I. Eachus wrote:

> Alexandre E. Kopilovitch wrote:
> 
>> While I was generally satisfied with that particular idiom for the need,
>> as well as with overall explanations given around it, nevertheless a
>> feeling remained that some final bit is still missing. And now I came to
>> an idea about that missing bit, that is, which thing is actually missing,
>> and how it can be provided.
>> 
>> So, I think that the primary problem with that idiom is that it may be
>> unknown for a programmer, and the secondary problem is that it isn't
>> always easily recognizable. In general, the missing thing is a reference
>> point for this idiom.
>> 
>> Therefore it seems suitable to introduce a pragma for this purpose - to
>> provide a reference point. This pragma will not affect the code, it will
>> merely state that the idiom is used for particular parameter of the
>> subroutine:
>> 
>>   pragma Mutable(subroutine-name, parameter-name); -- or
>>   Mutable_Parameter
> 
> First, I see absolutely nothing wrong with a project using this idea,
> even if the compiler doesn't support the pragma.  Second, it would be a
> very useful pragma for portable code that uses "the Rosen trick."

No, it is better never use tricks. The Rosen trick is in general an ability
for an object to identify itself in all context, even in ones stating
something opposite about it. That is an extremely dangerous thing, which
breaks substitutability and so the contract. Is this the motivation for
exposing this potential contract violation to code maintainer using a
pragma? But that would by no means solve the problem. It would make things
only worse. It would say, look, this is an in-parameter, but wait, that was
just joking, because, here is a pragma, carefully hidden somewhere else,
that states the opposite.

> But I have a different worry.  Cases where the Rosen trick are used are
> often for performance reasons, and are almost always equivalent to
> passing an access value instead of a record as the actual parameter.
> 
> If the fix for constructors of limited types becomes part of the next
> version of Ada, there will be a better way to deal with the issue.  The
>    Generator type in Ada.Numerics.Float_Random, and
> Ada.Numerics.Discrete_Random is declared limited private, and should be.
>   The same applies to any case where this trick is appropriate.  What
> you will be able to do with constructors for limited private objects in
> Ada 0Y is to make the object created on the stack of the correct size,
> and make the actual parameter type an access type.  Yeah, I know, this
> is a different cheat that works out to the same thing, but assuming the
> compiler supports it, growing the stack to create the actual object and
> doing the necessary initializations will result in something which is
> just as efficient as the Rosen trick but results in an access parameter
> which won't be altered.  (Its target will of course.)

Yes, this would be much better than the Rosen trick, for the reasons I
mentioned above. But I do not think that people will be happy with buzzing
'Access, aliased, 'Unchecked_Access all over the program. Hopefully this
would errode the position of purists, maybe.

> In case this sounds "over the top,"  I currently have a package I use
> that creates per task generators.  Of course, in that case you may need
> to do explicit allocate and free operations to keep the officially per
> task object small, but from a user perspective what is going on in all
> cases is the same.
> 
> I certainly don't know what the correct way to deal with the issue of
> access constant parameters is.  I think I would do it by allowing
> constant subtypes for access types.  Maybe in Ada 1Z?

That should be for *all* types then! For example:

type Object is ...;
subtype Read_Only is constant Object;

But better to provide all theoretically possible variants of subtypes. That
is:

1. in-subtype (= constant = in: no inout, out operations allowed =
specialization)

2. inout-subtype (= what we presently have)

3. out-subtype (= no in, inout operations = generalization)

Then something should be done with two keywords for the *same* thing. I mean
"constant" and "in".

> I don't think we know enough to fix that issue yet.  To clarify, there
> are two issues here.  One is that you want some access values to be
> marked as accessing constants, and in other cases you want to restrict
> the use of the designated object.

What is the difference? Or you mean to go further, and additionally to
support operation disallowing:

type Ball is ...;
procedure Spin (X : in out Game'Class; Y : Ball);

subtype Plain_Ball is Object;
procedure Spin (X : in out Game'Class; Y : Plain_Ball) is null;

> I feel that there is an elegant
> solution out there, but I don't know how to fill in all the blanks yet.)

Interface inheritance for all types is one. You inherit interface of an
access type and implement it in some different way, for example, by making
all mutators illegal.

> Let me give an example (assuming some new syntax where needed:
> 
>     type Foo is ...
>     type Bar is access Foo;
>     subtype CBar is access constant Foo;
>     F: Foo;

F : aliased Foo; -- I suppose

>     CF: constant Foo;

CF : constant aliased Foo;

There is a problem with renamings. Presently

CF : Foo renames Read_Foo (Stream);

breaks the contract! The result is not Foo, but in fact, constant Foo. This
is in breach with the concept of constant/in subtypes. It should be

CF : constant Foo renames Read_Foo (Stream);

But what to do with the backward compatibility?

>     B: Bar;
>     CB: CBar;
>     procedure Some_Proc(CBP: in CBar);
>     ...
>   begin
>     B := F'Access;  --okay
>     CB := CF'Access; -- no problem
>     B := CF'Access; -- illegal?

It is contradictory! Presently in Ada substitutability errors for the
predefined subtypes (in, inout, constant etc) are statically checkable and
the code with such errors is illegal. At the same time for the user-defined
subtypes these errors are subject of run-time checks and thus the code is
legal. IF "constant" becomes a user-defined subtype, then what to do with
this? It is a real problem, I see no good solution of. For example, if we
would make that all statically checkable violations illegal, then this
would break a lot of existing code.

>     CB := F'Access; -- should be okay?

Yes.

>     B := CB; -- illegal, or a run-time check?

Same as B := CF'Access;, we have a difficult problem here.

>     CB := B; -- should be okay.
>     Some_Proc(B); --should be okay, but...
>   ...
>     procedure Some_Proc(CBP: in CBar) is
>     ...
>     begin
>       CBP.Some_Comp := New_Value; -- must be illegal.

Yes. But where you see any problem? When B is passed to Some_Proc it is
*converted* to CBar. That is.

>       ...
>     end Some_Proc;
> 
> Just too many question marks in that prototype.  I'd want to prototype
> this and try to fill in the blanks, but only after some of the bigger
> pieces of Ada 0Y have been frozen.

IMO it would be difficult to make it in a consistent way without reviewing
the ADT model in Ada. But the time will come, I hope.

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



  reply	other threads:[~2004-01-03 11:18 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-02 17:55 Mutable parameter of a function (long ago was: Re: What evil would happen?) Alexandre E. Kopilovitch
2004-01-03  1:56 ` Robert I. Eachus
2004-01-03 11:18   ` Dmitry A. Kazakov [this message]
2004-01-04  0:58     ` Robert I. Eachus
2004-01-04 12:07       ` Dmitry A. Kazakov
2004-01-05  3:17         ` Alexandre E. Kopilovitch
2004-01-05  9:55           ` Dmitry A. Kazakov
2004-01-05 16:19             ` Robert I. Eachus
2004-01-06  3:04             ` Randy Brukardt
2004-01-06  9:32               ` Dmitry A. Kazakov
2004-01-06  3:01         ` Randy Brukardt
2004-01-06  9:26           ` Dmitry A. Kazakov
replies disabled

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