* Re-exporting primitive operations of a private type (like "-", and 'min) @ 2005-10-29 21:19 Anonymous Coward 2005-10-30 8:57 ` Dmitry A. Kazakov 2005-10-30 9:18 ` Jeffrey R. Carter 0 siblings, 2 replies; 17+ messages in thread From: Anonymous Coward @ 2005-10-29 21:19 UTC (permalink / raw) I'm bothered by the fact that the primitive operations of a parent are not inherited in a private type. In particular, the basic arithmetic operations are lost, like "+", "-", 'min, 'max, etc. There seems to be no clean way to re-export these operations, or am I missing something? Here is some sample code: [distance.ads] package Distance is type Public_Distance_Type is new Float; procedure Some_Procedure (Sample_Variable : in Public_Distance_Type); type Private_Distance_Type is private; Zero_Distance : constant Private_Distance_Type; Large_Distance : constant Private_Distance_Type; function "-" (Left, Right : in Private_Distance_Type) return Private_Distance_Type; private type Private_Distance_Type is new Public_Distance_Type; Zero_Distance : constant Private_Distance_Type := 0.0; Large_Distance : constant Private_Distance_Type := 999_999_999.0; end Distance; [distance.adb] package body Distance is function "-" (Left, Right : in Private_Distance_Type) return Private_Distance_Type is begin --This is ugly. Isn't there a way to declare this --operation without redefining it? The type casting --is also a nuissance, but the compiler warns of --infinite loops if casting is not used. return Private_Distance_Type(Public_Distance_Type(Left) - Public_Distance_Type(Right)); end "-"; procedure Some_Procedure (Sample_Variable : in Public_Distance_Type)is begin --This was another simple test to see whether we can --inherit explicitly declared public operations. null; end Some_Procedure; end Distance; [use_distance.adb] with Distance; procedure Use_Distance is Public_Distance : Distance.Public_Distance_Type; Private_Distance : Distance.Private_Distance_Type; use type Distance.Private_Distance_Type; use type Distance.Public_Distance_Type; begin Public_Distance := Distance.Public_Distance_Type'Min(-5.0,7.0); --The following line fails to compile because --'min is not inherited. -- --Private_Distance := Distance.Private_Distance_Type'Min -- (Distance.Zero_Distance,Distance.Large_Distance); Distance.Some_Procedure (Sample_Variable => Public_Distance); --The following line fails to compile because --Some_Procedure is not inherited. -- --Distance.Some_Procedure (Sample_Variable => Private_Distance); --This line compiles because it was redefined explicitly -- Private_Distance := Distance.Large_Distance - Distance.Zero_Distance; end Use_Distance; --- Redefining "-" is an annoyance. I'm not even sure how to redefine attribute operations like 'min. Suggestions? ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-29 21:19 Re-exporting primitive operations of a private type (like "-", and 'min) Anonymous Coward @ 2005-10-30 8:57 ` Dmitry A. Kazakov 2005-10-30 9:18 ` Jeffrey R. Carter 1 sibling, 0 replies; 17+ messages in thread From: Dmitry A. Kazakov @ 2005-10-30 8:57 UTC (permalink / raw) On Sat, 29 Oct 2005 21:19:27 GMT, Anonymous Coward wrote: > I'm bothered by the fact that the primitive operations of a parent are > not inherited in a private type. They are but in the view where inheritance happens. In your example it happens in the private view. > In particular, the basic arithmetic > operations are lost, like "+", "-", 'min, 'max, etc. "+' and "-" are rather hidden. > There seems to > be no clean way to re-export these operations, Yep. That's because the original operation cannot be named. Otherwise, one could just rename new "-" to the old one. As for attributes, it is another case, they cannot be user-defined at all. > Redefining "-" is an annoyance. In general, the problem is that old-fashioned way emerged before Ada became OO. Private_Distance_Type is a numeric type. That should be its *public* contract. But in Ada it is impossible to specify things like this for non-tagged types [outside generics, to be precise.] The compiler cannot recognize the programmer's intent from a bunch of operations declared in the public part. So it does not. Therefore when in the private part Private_Distance_Type gets implemented as a clone of a numeric type, the compiler treats public "-" as a different operation declared. [ I'm not sure if interfaces of Ada 2005 might help here. Let's wait for a working compiler. ] Anyway, you could go this way: ... private type Most_Private_Distance_Type is new Public_Distance_Type; function Sub (Left, Right : in Most_Private_Distance_Type) return Most_Private_Distance_Type renames "-"; -- Renaming "as-declaration" creates a new primitive operation Sub type Private_Distance_Type is new Most_Private_Distance_Type; -- Both "-" and Sub are inherited, but "-" gets hidden by "-" -- declared in the public part function "-" (Left, Right : in Private_Distance_Type) return Private_Distance_Type renames Sub; -- Renaming "as-body" implements public "-" through private "-" -- via Sub Warning, this may crash GNAT 3.15p which has many bugs in visibility rules (let language lawyers correct me if I'm wrong and the above is illegal.) I didn't try such things with GNAT GPL but it is even more buggy. (:-() > I'm not even sure how to redefine > attribute operations like 'min. Suggestions? They aren't "normal" operations, as they should be, so forget about them. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-29 21:19 Re-exporting primitive operations of a private type (like "-", and 'min) Anonymous Coward 2005-10-30 8:57 ` Dmitry A. Kazakov @ 2005-10-30 9:18 ` Jeffrey R. Carter 2005-10-30 14:16 ` Martin Krischik 2005-10-31 4:15 ` Anonymous Coward 1 sibling, 2 replies; 17+ messages in thread From: Jeffrey R. Carter @ 2005-10-30 9:18 UTC (permalink / raw) Anonymous Coward wrote: > --The following line fails to compile because > --'min is not inherited. > -- > --Private_Distance := Distance.Private_Distance_Type'Min > -- (Distance.Zero_Distance,Distance.Large_Distance); > > Distance.Some_Procedure (Sample_Variable => Public_Distance); > > --The following line fails to compile because > --Some_Procedure is not inherited. > -- > --Distance.Some_Procedure (Sample_Variable => Private_Distance); The whole point of private types is that the only visible operations on them are assignment, equality and inequality, and any explicitly defined operations in the visible part of the package specification. Thus, 'Min is not defined for the type because it is not visibly a numeric or enumeration type. Some_Procedure is not defined for the type because you did not define such a procedure for the type. "-" is defined only because you did define "-" for the type, not because of its full type definition. You can have any full type definition for the type that allows assignment and equality. It could be an array of records. Again, the only visible operations for the type are assignment, equality, and those explicitly defined in the package. The full type declaration is not visible, and the fact that it gives the type certain operations not declared in the package specification does not change the set of visible operations. Those additional operations are only visible where the full type definition is visible. Another way of saying this is that the full type definition has no effect on the client's view of the type. > Redefining "-" is an annoyance. I'm not even sure how to redefine > attribute operations like 'min. Suggestions? Redefining a predefined operation such as "-" *is* a pain. The problem is that once you declare "-" for the type, that declaration hides the predefined operation, and there's no way to refer to the predefined operation after that. That's why you have to convert to a suitable numeric type, invoke the equivalent operation for that type, and then convert back to the private type. (Note that "casting" is not an Ada term. I presume from context that you were referring to type conversions.) However, you only have to define the operations once, so it's a limited amount of pain. It might be nice to have a way to define opaque numeric types, but, for better or worse, that's not a path that Ada took. It's lack is most often felt in defining generics. There are situations in which a generic could operate on any numeric type. Ada has no easy way to define such a generic. -- Jeff Carter "C++ is like jamming a helicopter inside a Miata and expecting some sort of improvement." Drew Olbrich 51 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-30 9:18 ` Jeffrey R. Carter @ 2005-10-30 14:16 ` Martin Krischik 2005-10-30 22:35 ` Robert A Duff 2005-10-31 4:15 ` Anonymous Coward 1 sibling, 1 reply; 17+ messages in thread From: Martin Krischik @ 2005-10-30 14:16 UTC (permalink / raw) Am 30.10.2005, 11:18 Uhr, schrieb Jeffrey R. Carter <spam@spam.com>: > That's why you have to convert to a suitable numeric type, invoke the > equivalent operation for that type, and then convert back to the private > type. Would 'Base not be a suitable type? Martin ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-30 14:16 ` Martin Krischik @ 2005-10-30 22:35 ` Robert A Duff 0 siblings, 0 replies; 17+ messages in thread From: Robert A Duff @ 2005-10-30 22:35 UTC (permalink / raw) "Martin Krischik" <krischik@users.sourceforge.net> writes: > Am 30.10.2005, 11:18 Uhr, schrieb Jeffrey R. Carter <spam@spam.com>: > > > That's why you have to convert to a suitable numeric type, invoke the > > equivalent operation for that type, and then convert back to the > > private type. > > Would 'Base not be a suitable type? No, T'Base returns a subtype, but it's same _type_ as T. So whatever operations you do will be those of T. - Bob ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-30 9:18 ` Jeffrey R. Carter 2005-10-30 14:16 ` Martin Krischik @ 2005-10-31 4:15 ` Anonymous Coward 2005-10-31 4:34 ` Anonymous Coward ` (2 more replies) 1 sibling, 3 replies; 17+ messages in thread From: Anonymous Coward @ 2005-10-31 4:15 UTC (permalink / raw) > The whole point of private types is that the only visible operations > on them are assignment, equality and inequality, and any explicitly > defined operations in the visible part of the package > specification. That makes sense. As a default, it probably would be a poor language design to have private types automatically export public primitive operations. If I created an Altitude_Type, I wouldn't want to inherit the "+" operation. However, I was hoping for a one liner (or a pragma) that would enable me to explicitly declare operations for public use. The fact that these must be redefined really seems like a short-coming of the language. Anyway, it's not the end of the world. I mainly just wanted to get an idea for cleanest way to handle this dirty situation.. and I like the suggestions you folks made. I appreciate all your advice. I haven't decided which approach I like better, but here's what my sample code looks like right now: [distance.ads] package Distance is type Public_Distance_Type is new Float; type Private_Distance_Type is private; Zero_Distance : constant Private_Distance_Type; Large_Distance : constant Private_Distance_Type; function "-" (Left, Right : in Private_Distance_Type) return Private_Distance_Type; function "+" (Left, Right : in Private_Distance_Type) return Private_Distance_Type; private type Private_Distance_Type is new Public_Distance_Type; Zero_Distance : constant Private_Distance_Type := 0.0; Large_Distance : constant Private_Distance_Type := 999_999_999.0; end Distance; [distance.adb] package body Distance is -- Implementation operations ------------------------------------------------ function Subtract (Left, Right : in Private_Distance_Type) return Private_Distance_Type is begin --Kazakov's suggested approach. This is good because it's --simple, and doesn't require type conversions. --(May not work with gnat 3.15p) return (Left - Right); end Subtract; -- Public operations -------------------------------------------------------- function "-" (Left, Right : in Private_Distance_Type) return Private_Distance_Type renames Subtract; function "+" (Left, Right : in Private_Distance_Type) return Private_Distance_Type is begin --Krischik's suggested approach. This is better than what I --had started with because I don't need to reference the --parent type explicitly. return Private_Distance_Type(Private_Distance_Type'Base(Left) - Private_Distance_Type'Base(Right)); end "+"; end Distance; [use_distance.adb] with Distance; procedure Use_Distance is Public_Distance : Distance.Public_Distance_Type; Private_Distance : Distance.Private_Distance_Type; use type Distance.Private_Distance_Type; use type Distance.Public_Distance_Type; begin --This operation is forever invisible in the --Private_Distance_Type, and can only be declared as an --operation with a new name. -- Public_Distance := Distance.Public_Distance_Type'Min(-5.0,7.0); --These lines compile only because they are redefined explicitly, using function overloading. -- Private_Distance := Distance.Large_Distance - Distance.Zero_Distance; Private_Distance := Distance.Large_Distance + Distance.Zero_Distance; end Use_Distance; --- In my real life case, there is no Public_Distance_Type. It's really just derived from a Float, but I use it here for clarity and testing purposes. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-31 4:15 ` Anonymous Coward @ 2005-10-31 4:34 ` Anonymous Coward 2005-10-31 6:14 ` Jeffrey R. Carter 2005-10-31 8:27 ` Niklas Holsti 2 siblings, 0 replies; 17+ messages in thread From: Anonymous Coward @ 2005-10-31 4:34 UTC (permalink / raw) Oops, I posted too soon. That code for "-" compiles, but gives a segmentation fault when it runs. Could it be the problem Kazakov warned of in 3.15p? Here is my version: # rpm -qi gcc Name : gcc Relocations: (not relocateable) Version : 3.2.2 Vendor: Red Hat, Inc. Release : 5 Build Date: Tue 25 Feb 2003 06:53:15 AM MST Install Date: Thu 24 Jul 2003 05:55:48 AM MDT Build Host: stripples.devel.redhat.com Group : Development/Languages Source RPM: gcc-3.2.2-5.src.rpm Size : 11592745 License: GPL Signature : DSA/SHA1, Tue 25 Feb 2003 08:04:13 AM MST, Key ID 219180cddb42a60e Packager : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla> URL : http://gcc.gnu.org Summary : The GNU cc and gcc C compilers. Description : The gcc package includes the cc and gcc GNU compilers for compiling C code. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-31 4:15 ` Anonymous Coward 2005-10-31 4:34 ` Anonymous Coward @ 2005-10-31 6:14 ` Jeffrey R. Carter 2005-11-01 3:39 ` Anonymous Coward 2005-10-31 8:27 ` Niklas Holsti 2 siblings, 1 reply; 17+ messages in thread From: Jeffrey R. Carter @ 2005-10-31 6:14 UTC (permalink / raw) Anonymous Coward wrote: > function Subtract (Left, Right : in Private_Distance_Type) > return Private_Distance_Type is > > begin > > --Kazakov's suggested approach. This is good because it's > --simple, and doesn't require type conversions. > --(May not work with gnat 3.15p) > > return (Left - Right); > > end Subtract; This isn't going to work. Subtract has to be defined for the private type's parent (as a renaming of "-"), so the private type also has Subtract defined. Then you can define "-" for the private type as a renaming of Subtract. Here, "-" refers to the explicitly defined operation, which is a renaming of Subtract, so this is infinite recursion. -- Jeff Carter "There's no messiah here. There's a mess all right, but no messiah." Monty Python's Life of Brian 84 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-31 6:14 ` Jeffrey R. Carter @ 2005-11-01 3:39 ` Anonymous Coward 2005-11-01 4:47 ` Jeffrey R. Carter 2005-11-01 14:11 ` Robert A Duff 0 siblings, 2 replies; 17+ messages in thread From: Anonymous Coward @ 2005-11-01 3:39 UTC (permalink / raw) In article <iDi9f.3949$yX2.741@newsread2.news.pas.earthlink.net>, Jeffrey R. Carter wrote: > Anonymous Coward wrote: > >> function Subtract (Left, Right : in Private_Distance_Type) >> return Private_Distance_Type is >> >> begin >> >> --Kazakov's suggested approach. This is good because it's >> --simple, and doesn't require type conversions. >> --(May not work with gnat 3.15p) >> >> return (Left - Right); >> >> end Subtract; > > This isn't going to work. Subtract has to be defined for the private > type's parent (as a renaming of "-"), so the private type also has > Subtract defined. Then you can define "-" for the private type as a > renaming of Subtract. > > Here, "-" refers to the explicitly defined operation, which is a > renaming of Subtract, so this is infinite recursion. You seem to be correct. The segmentation fault was probably due to running out of stack space because of an infinite recursion. I didn't suspect that at first, because I didn't get the compiler warning about infinite recursion this time, so it seems the renaming made put the flaw beyond gnats detection. So in the end, the 'base technique doesn't work either, and I'm left with type conversions that explicitly reference the parent: function "-" (Left, Right : in Private_Distance_Type) return Private_Distance_Type is begin return Private_Distance_Type(Public_Distance_Type(Left) - Public_Distance_Type(Right)); end "-"; Did someone say ADA 2005 will handle this better? When is ADA 2005 expected to roll out? ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-11-01 3:39 ` Anonymous Coward @ 2005-11-01 4:47 ` Jeffrey R. Carter 2005-11-01 23:43 ` Anonymous Coward 2005-11-01 14:11 ` Robert A Duff 1 sibling, 1 reply; 17+ messages in thread From: Jeffrey R. Carter @ 2005-11-01 4:47 UTC (permalink / raw) Anonymous Coward wrote: > > So in the end, the 'base technique doesn't work either, and I'm left > with type conversions that explicitly reference the parent: You should be able to say (in the private part) function Subtract (Left, Right : in Public_Distance_Type) return Public_Distance_Type renames "-"; type Private_Distance_Type is new Public_Distance_Type; -- Subtract is defined for Private_Distance_Type. function "-" (Left, Right : in Private_Distance_Type) return Private_Distance_Type renames Subtract; -- Jeff Carter "Son of a window-dresser." Monty Python & the Holy Grail 12 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-11-01 4:47 ` Jeffrey R. Carter @ 2005-11-01 23:43 ` Anonymous Coward 2005-11-02 3:35 ` Jeffrey R. Carter 0 siblings, 1 reply; 17+ messages in thread From: Anonymous Coward @ 2005-11-01 23:43 UTC (permalink / raw) In article <ErC9f.4432$yX2.1697@newsread2.news.pas.earthlink.net>, Jeffrey R. Carter wrote: > > You should be able to say (in the private part) > > function Subtract (Left, Right : in Public_Distance_Type) > return Public_Distance_Type renames "-"; > > type Private_Distance_Type is new Public_Distance_Type; > -- Subtract is defined for Private_Distance_Type. > > function "-" (Left, Right : in Private_Distance_Type) > return Private_Distance_Type renames Subtract; That would probably work as long as the definition of Subtract does a type conversion explicitly on the Left and Right to the parent types. But what are the advantages? Why would I define a Subtract operation and use a renames clause, when I can simply define a "-" operation directly? The "-" operation must still be replaced, and it still has to have a declaration in the public part. So in your case above, there would have to be a function "-" (Left, Right : in Private_Distance_Type) return Private_Distance_Type; in the public part. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-11-01 23:43 ` Anonymous Coward @ 2005-11-02 3:35 ` Jeffrey R. Carter 0 siblings, 0 replies; 17+ messages in thread From: Jeffrey R. Carter @ 2005-11-02 3:35 UTC (permalink / raw) Anonymous Coward wrote: > That would probably work as long as the definition of Subtract does a > type conversion explicitly on the Left and Right to the parent types. > But what are the advantages? Why would I define a Subtract operation > and use a renames clause, when I can simply define a "-" operation > directly? No. Subtract is defined for the parent type as a renaming of "-". Thus, calling Subtract is the same as calling "-". The private type derives from the parent type after the declaration of Subtract, so it also has Subtract defined as a renaming of the predefined "-". It also has a redefined "-" that must be explicitly defined. The redefined "-" is then defined as a renaming of Subtract, so calling the redefined "-" is the same as calling Subtract, and calling Subtract is the same as calling the predefined "-". That's kind of a mouthful, but it means the explicitly defined "-" for the private type is actually the predefined "-". The advantage of this approach is that "-" remains the predefined operation for the type. It may also be a little shorter and easier to get right. > The "-" operation must still be replaced, and it still has to have a > declaration in the public part. So in your case above, there would > have to be a > > function "-" (Left, Right : in Private_Distance_Type) > return Private_Distance_Type; > > in the public part. Certainly. That's the only reason you'd go through all this. -- Jeff Carter "In the frozen land of Nador they were forced to eat Robin's minstrels, and there was much rejoicing." Monty Python & the Holy Grail 70 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-11-01 3:39 ` Anonymous Coward 2005-11-01 4:47 ` Jeffrey R. Carter @ 2005-11-01 14:11 ` Robert A Duff 1 sibling, 0 replies; 17+ messages in thread From: Robert A Duff @ 2005-11-01 14:11 UTC (permalink / raw) Anonymous Coward <bogus_addy@bogus_domain.net> writes: > You seem to be correct. The segmentation fault was probably due to > running out of stack space because of an infinite recursion. Yes. Some compilers do not have stack checking turned on by default. If not, there is an option to turn it on, in which case infinite recursion will raise Storage_Error, which might be easier to debug. - Bob ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-31 4:15 ` Anonymous Coward 2005-10-31 4:34 ` Anonymous Coward 2005-10-31 6:14 ` Jeffrey R. Carter @ 2005-10-31 8:27 ` Niklas Holsti 2005-10-31 9:18 ` Dmitry A. Kazakov 2005-11-02 9:50 ` Jean-Pierre Rosen 2 siblings, 2 replies; 17+ messages in thread From: Niklas Holsti @ 2005-10-31 8:27 UTC (permalink / raw) Anonymous Coward wrote: >>The whole point of private types is that the only visible operations >>on them are assignment, equality and inequality, and any explicitly >>defined operations in the visible part of the package >>specification. > > > That makes sense. As a default, it probably would be a poor language > design to have private types automatically export public primitive > operations. If I created an Altitude_Type, I wouldn't want to inherit > the "+" operation. The following is perhaps not quite on the original topic, but this thread reminds me of an idea for a new feature related to private types that I would like to present. My Ada packages often define types that are *mostly* private in the sense that I only want the clients to use a restricted set of operations and properties of the type. However, I often do not make these types actual private types because I want to reveal some properties, such as discreteness, that I cannot now specify for a private type. I would like to be able to reveal some properties of private types in the same way as we can now define generic formal types, for example saying that the type is discrete (type T is (<>)) or is a modular type (type T is mod <>). So I would like to write, for example, a package like this: package P is type Element is private (<>); -- This is not Ada. The intended meaning is that type -- Element is private, but is a discrete type. -- Some operations using Element. private type Element is (This, That, The_Other); -- See, Element is really a discrete type. end P; Other (client) packages can then use the fact that P.Element is a discrete type, for example by using P.Element as an index type: with P; package Client is type Set is array (P.Element) of Boolean; ... end Client; However, the whole definition of P.Element would still be hidden, so clients could not refer for example to P.Element'(P.This). There would be a pleasing symmetry in this new feature if the properties that could be revealed about a private type would match exactly the properties that can now be defined for a generic formal type. A private type with some properties revealed in this way could then be used as the actual type to instantiate a generic with a formal type that has matching properties. There are even some places in the Ada LRM where the proposed feature would be useful. For example, the LRM (95) now defines, in 13.7.1: package System.Storage_Elements is ... type Storage_Offset is range "implementation defined"; ... type Storage_Element is mod "implementation defined"; ... end System.Storage_Elements; With the new feature, the "implementation defined" pseudocode could be replaced by real code: type Storage_Offset is private range <>; -- Not Ada. type Storage_Element is private mod <>; -- Not Ada. The full type declarations would be in the private part of the package, as usual. In such declarations, the "private" keyword is perhaps unnecessary, since the presence of the box "<>" shows that the declared type is partly hidden. Does this idea appeal to anyone? -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-31 8:27 ` Niklas Holsti @ 2005-10-31 9:18 ` Dmitry A. Kazakov 2005-11-02 9:50 ` Jean-Pierre Rosen 1 sibling, 0 replies; 17+ messages in thread From: Dmitry A. Kazakov @ 2005-10-31 9:18 UTC (permalink / raw) On Mon, 31 Oct 2005 10:27:51 +0200, Niklas Holsti wrote: > Anonymous Coward wrote: >>>The whole point of private types is that the only visible operations >>>on them are assignment, equality and inequality, and any explicitly >>>defined operations in the visible part of the package >>>specification. >> >> That makes sense. As a default, it probably would be a poor language >> design to have private types automatically export public primitive >> operations. If I created an Altitude_Type, I wouldn't want to inherit >> the "+" operation. > > The following is perhaps not quite on the original topic, but this > thread reminds me of an idea for a new feature related to private > types that I would like to present. > > My Ada packages often define types that are *mostly* private in > the sense that I only want the clients to use a restricted set of > operations and properties of the type. However, I often do not > make these types actual private types because I want to reveal > some properties, such as discreteness, that I cannot now specify > for a private type. > > I would like to be able to reveal some properties of private types > in the same way as we can now define generic formal types, for > example saying that the type is discrete (type T is (<>)) or is a > modular type (type T is mod <>). [...] > Does this idea appeal to anyone? That would a repetition of the error made with generics. Instead of type Element is private (<>); it should be just type Element is new Abstract_Integer with private; which would solve everything. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-10-31 8:27 ` Niklas Holsti 2005-10-31 9:18 ` Dmitry A. Kazakov @ 2005-11-02 9:50 ` Jean-Pierre Rosen 2005-11-03 9:15 ` Niklas Holsti 1 sibling, 1 reply; 17+ messages in thread From: Jean-Pierre Rosen @ 2005-11-02 9:50 UTC (permalink / raw) Niklas Holsti a �crit : > With the new feature, the "implementation defined" pseudocode could be > replaced by real code: > > type Storage_Offset is private range <>; -- Not Ada. > type Storage_Element is private mod <>; -- Not Ada. > > The full type declarations would be in the private part of the package, > as usual. > > In such declarations, the "private" keyword is perhaps unnecessary, > since the presence of the box "<>" shows that the declared type is > partly hidden. > > Does this idea appeal to anyone? > I fail to see the benefit. The only thing that would be "hidden" with such a declaration is the actual value of the bounds. But you could get them with 'First and 'Last. So, there would be no benefit in pretending that they are "private". -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Visit Adalog's web site at http://www.adalog.fr ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re-exporting primitive operations of a private type (like "-", and 'min) 2005-11-02 9:50 ` Jean-Pierre Rosen @ 2005-11-03 9:15 ` Niklas Holsti 0 siblings, 0 replies; 17+ messages in thread From: Niklas Holsti @ 2005-11-03 9:15 UTC (permalink / raw) Jean-Pierre Rosen wrote: > Niklas Holsti a �crit : > >> With the new feature, the "implementation defined" pseudocode could be >> replaced by real code: >> >> type Storage_Offset is private range <>; -- Not Ada. >> type Storage_Element is private mod <>; -- Not Ada. >> >> The full type declarations would be in the private part of the >> package, as usual. >> >> In such declarations, the "private" keyword is perhaps unnecessary, >> since the presence of the box "<>" shows that the declared type is >> partly hidden. >> >> Does this idea appeal to anyone? >> > I fail to see the benefit. The only thing that would be "hidden" with > such a declaration is the actual value of the bounds. But you could get > them with 'First and 'Last. So, there would be no benefit in pretending > that they are "private". I think there would be a benefit -- it would *force* the clients of this package to use 'First and 'Last, instead of other *not standardized* items, for example some named numbers that may be defined in a particular implementation of this package. But I agree that the advantage in this example is small. Let me explain the context more clearly. You have an Ada program that contains a package A which defines a type A.T, and a package B that uses A.T in some way. For some reason (say, different platforms or different product variants) you have several variants of package A, say A', A" and so on. They all have the Ada name A, but they exist in different source directories, for example. To build a particular version of this program, you select a variant of A and compile it together with B. The variants define the type A.T in different ways; A' may define it as an enumeration, A" as an integer type, etc. You want the same package B to be compatible with all variants of package A, even though the different variants of type A.T differ in detail. Thus, there must be some form of contract or specification that every variant of type A.T must satisfy and which defines how package B can use type A.T. The only way to express such a contract in Ada, now, is to define A.T as (fully) private and provide the necessary operations in package A. But this means that A.T cannot be (visibly) discrete, so it cannot be used as an array index, cannot be used as a discriminant, and cannot be an actual type in generic instantiations where the formal type is more specific than "private". An alternative would be to make package B generic, with a generic formal type standing for A.T, and then instantiate B with whatever variant of A.T is at hand. The definition of the generic parameters of B then define the contract. However, this method is not very practical when there are many packages (B, C, D, ... ZZ) that depend on A.T, and perhaps on other packages with variants. Moreover, it seems like overkill when you know that there will be only a single instantiation of B (and C, D, ... ZZ) in any version of the program. The contract aspect of Ada generics is a good thing, but it is one-sided: it only lets the generic unit specify what it *expects* of a type that it will be given; there is now no similar way to specify what a unit *promises* of a type that it *provides*. One can only define a public type, which usually overspecifies the contract, or a (fully) private type, which has limitations as I said above. My proposal aims for a similar contract aspect for private types, to let the provider of a type specify the type's properties without forcing "the rest of the world" to be defined as generic and parametrized with this type. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2005-11-03 9:15 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2005-10-29 21:19 Re-exporting primitive operations of a private type (like "-", and 'min) Anonymous Coward 2005-10-30 8:57 ` Dmitry A. Kazakov 2005-10-30 9:18 ` Jeffrey R. Carter 2005-10-30 14:16 ` Martin Krischik 2005-10-30 22:35 ` Robert A Duff 2005-10-31 4:15 ` Anonymous Coward 2005-10-31 4:34 ` Anonymous Coward 2005-10-31 6:14 ` Jeffrey R. Carter 2005-11-01 3:39 ` Anonymous Coward 2005-11-01 4:47 ` Jeffrey R. Carter 2005-11-01 23:43 ` Anonymous Coward 2005-11-02 3:35 ` Jeffrey R. Carter 2005-11-01 14:11 ` Robert A Duff 2005-10-31 8:27 ` Niklas Holsti 2005-10-31 9:18 ` Dmitry A. Kazakov 2005-11-02 9:50 ` Jean-Pierre Rosen 2005-11-03 9:15 ` Niklas Holsti
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox