comp.lang.ada
 help / color / mirror / Atom feed
From: "Yannick Duchêne (Hibou57)" <yannick_duchene@yahoo.fr>
Subject: Re: Overring function and its returned type
Date: Sat, 10 Nov 2012 01:28:54 +0100
Date: 2012-11-10T01:28:54+01:00	[thread overview]
Message-ID: <op.wni7mghiule2fv@cardamome> (raw)
In-Reply-To: op.wniye3txule2fv@cardamome

Le Fri, 09 Nov 2012 22:10:05 +0100, Yannick Duchêne (Hibou57)  
<yannick_duchene@yahoo.fr> a écrit:
> I will also try to workaround with an overloading instead of an  
> overriding, but I'm afraid of getting into a mess with this solution.  
> Will choose which cause the less troubles, and although the  
> postcondition+conversion solution looks like bloat, I believe that's  
> still the safest. I will still try both to really get an idea…

Two attempts, with a comment comparing both at the end.


First attempt
=============

Something I tried, which lead to an interesting issue. I don't know if  
GNAT is right or wrong, this will require a careful reading of the RM.

Replace `P3` spec with:


        package P3 is

           type R is new P1.R with null record;
           type T is new P1.T with null record;

           overriding
           function F
             (E : T)
              return P1.R'Class
              with Post'Class =>
                 F'Result in R'Class;

           -- Not a primitive operation.
           function F
             (E : T'Class)
              return R'Class
              is (R'Class (P1.T (E).F));
        end;


And a use case, which fails:


        A : P3.T;
        B : P1.R'Class := A.F;
        C : P3.R'Class := A.F; -- Fails here


That's C's assignment which fails. Seems GNAT cannot resolve it figure it  
refers to the second `F` function (it does not even complains about an  
ambiguity). Will have to look at the RM for it. I feel this should be OK  
and could be resolved as expected, but may be the RM states otherwise.

The second `F` function cannot be a primitive, due to its “inline”  
expression.


Second attempt
==============

Another way to solve it:


        package P3 is

           type R is new P1.R with null record;
           type T is new P1.T with null record;

           overriding
           function F
             (E : T)
              return P1.R'Class
              with Post'Class =>
                 F'Result in R'Class;

           not overriding
           function F
             (E : T)
              return R'Class;
        end;

        -- ----------------------------------------

        package body P3 is

           overriding
           function F
             (E : T)
              return P1.R'Class
           is
              X : R;
           begin
              return X;
           end;

           not overriding
           function F
             (E : T)
              return R'Class
           is begin
              return R'Class (P1.T (E).F);
           end;
        end;


And the sample use case:


        A : P3.T;
        B : P1.R'Class := A.F; -- Fails here
        C : P3.R'Class := A.F;


Assignment to `B` is considered ambiguous, but that's not an issue, as  
only the case corresponding to the assignment to `C` is expected. Anyway,  
the case of the assignment to `B` can be solved this way:


        B : P1.R'Class := P1.R'Class'(A.F); -- Resolved ambiguity


Comparing both
==============

What's nice with the first attempt, is that what's returned is explicitly  
shown in the spec. What's nice with the second attempt, is that it works  
(good point, cheese), and that it's a primitive (if ever that matters  
really), but as a cons, it is not as explicit as in the first attempt.

May be the best solution is to do as in the second attempt, and give the  
second `F` function, a comment “specifying” the returned result is exactly  
the same as the with the first `F`, expect explicitly of type `R'Class`.

That's not as clean as one could expect, but at least I don't see it as  
presenting any potential issues in the case where `P1` holds a primitive  
with a predicate referring to `F`. The human reader could infer such a  
predicate would applies to the second `F` function too, as long as it is  
clear enough both returns the same thing, except for their explicit types.  
The compiler won't know, but the human reader will.


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University



  parent reply	other threads:[~2012-11-10  0:29 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-09  7:13 Overring function and its returned type Yannick Duchêne (Hibou57)
2012-11-09  7:22 ` Yannick Duchêne (Hibou57)
2012-11-09  8:24 ` Dmitry A. Kazakov
2012-11-09  9:14   ` Yannick Duchêne (Hibou57)
2012-11-09 13:11     ` Dmitry A. Kazakov
2012-11-09 21:36       ` Yannick Duchêne (Hibou57)
2012-11-09 19:24   ` Adam Beneschan
2012-11-09 19:34 ` Adam Beneschan
2012-11-09 22:00   ` J-P. Rosen
2012-11-09 22:30     ` Yannick Duchêne (Hibou57)
2012-11-09 19:57 ` sbelmont700
2012-11-09 21:10   ` Yannick Duchêne (Hibou57)
2012-11-09 21:56     ` sbelmont700
2012-11-10  0:28     ` Yannick Duchêne (Hibou57) [this message]
2012-11-10  2:35       ` Yannick Duchêne (Hibou57)
2012-11-15 15:13   ` Peter C. Chapin
2012-11-16 10:40     ` Maciej Sobczak
2012-11-16 12:39       ` Peter C. Chapin
2012-11-16 15:27         ` Maciej Sobczak
2012-11-16 17:29           ` Peter C. Chapin
2012-11-17  4:16           ` Yannick Duchêne (Hibou57)
2012-11-17 19:11             ` Robert A Duff
2012-11-18 14:53               ` AdaMagica
2012-11-19  8:41                 ` Yannick Duchêne (Hibou57)
2012-11-19 13:04                   ` AdaMagica
2012-11-19 15:19                     ` Dmitry A. Kazakov
2012-11-19 23:42                   ` Randy Brukardt
2012-11-10  7:55 ` Randy Brukardt
2012-11-11  1:02   ` Yannick Duchêne (Hibou57)
replies disabled

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