Entomy / Ada-Improvements

Repository of Ada language improvement ideas
GNU General Public License v3.0
4 stars 0 forks source link

Deferred Partial Instantiation of Generic Specifications #33

Open jere-software opened 4 years ago

jere-software commented 4 years ago

Should Support:


    generic
       type Type1 is private;
       with function Image(Value : Type1) return String;
    package My_Client_Package is new My_Package
       (Type1     => Type1,
        Type2     => Integer,
        Type3     => String,
        Something => Something_For_Integer_And_String,
        Image     => Image);

Rationale:

See https://github.com/AdaCore/ada-spark-rfcs/pull/41 for full details.

The intent of this is to allow partial specializations of generics so that one can more easily lay out complex designs using "core" generics that may have a lot of formals in order to cover various use cases. This feature would allow one to take such a "core" generic and make a more "client friendly" formal parameter list. Consider a core generic:

    generic
       type Type1 is private;
       type Type2 is limited private;
       type Type3(<>);
       with procedure Something(Param1 : Type2; Param2 : Type3);
       with function Image(Value : Type1) return String;
    package My_Package is
       procedure Yay(Value : Type1);  -- calls Image internally
       -- Other Stuff
    end My_Package;

The general 99% use case for that might really only need to supply Type1 and Image, but in order to cover some internal implementations or special niche cases, Type2, Type3, and Something are necessary. However, it may not be intuitive for a general user. This suggests the new syntax so that the user of a library can instantiate packages this way:


    package P is new My_Client_Package (My_Type, Image_For_My_Type); 

and not have to worry about the more complex formal parameters.

Current Ada would require either manually recreating the API of My_Package inside of My_Client_Package and doing all the scaffolding, a maintenance and error hazard. Alternately one might instantiate an instance of My_Package inside of My_Client_Package, but then one would have to call P1.P2.Yay, with the P2 being superfluous and only there because there isn't a much better way, not because the design itself requires it.