From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=BAYES_00,MSGID_RANDY autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,989d0c2f2f87320d X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-01-12 16:38:04 PST Path: supernews.google.com!sn-xit-03!supernews.com!news-feed.riddles.org.uk!newsfeed.direct.ca!look.ca!logbridge.uoregon.edu!newsfeed.berkeley.edu!ucberkeley!nntp2.deja.com!nnrp1.deja.com!not-for-mail From: mark_lundquist@my-deja.com Newsgroups: comp.lang.ada Subject: Re: Record type with check? Date: Sat, 13 Jan 2001 00:19:53 GMT Organization: Deja.com Message-ID: <93o6v2$dbi$1@nnrp1.deja.com> References: <868zolm9dp.fsf@book.mteege.de> <87hf373l3a.fsf@moon.mteege.de> <93ikth$ik5$1@nnrp1.deja.com> NNTP-Posting-Host: 130.213.204.167 X-Article-Creation-Date: Sat Jan 13 00:19:53 2001 GMT X-Http-User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt) X-Http-Proxy: 1.1 x72.deja.com:80 (Squid/1.1.22) for client 130.213.204.167 X-MyDeja-Info: XMYDJUIDmark_lundquist Xref: supernews.google.com comp.lang.ada:3973 Date: 2001-01-13T00:19:53+00:00 List-Id: In article <93ikth$ik5$1@nnrp1.deja.com>, Robert Dewar wrote: > In article <87hf373l3a.fsf@moon.mteege.de>, > Matthias Teege wrote: > > If nobody knows a > > better representation I'll made a private type. ;-) > > A private type *IS* a better representation. Nearly all types > should be private if they are at all complex, and most > certainly if invariants like this are to be preserved, the > appropriate interface is an abstract data type. Matthias, don't say "I'll make it private if I have to", say "I'll make it _public_ only if I have to!" The full heuristic is something like this: 1) Don't assume all type definitions belong in a package spec. Before putting a type in a spec, consider whether it might really belong in the body. That's the essence of the advice in Nick Roberts' post (one way to look at it anyway -- another is "think abstraction first, representation second"). This is not at all to say it's categorically more desirable for type definitions to be in a body. Just think about it, that's all. If the essence of the abstraction is that clients declare instances of it, then it belongs in the spec; if it's needed to implement something within the body, put it in the body. (You wouldn't, for instance, decide to use an "opaque handle" idiom for everything, just to keep types out of specs...) 2) If the type belongs in the spec, it should go in the private part unless you have a reason for it to be public... Now if it's private, there are two ways to have better control over the abstraction: 2a) Make the public view limited. Then clients cannot do assignment of instances of the type. You control whether they can test for equality (because you have to provide "="), and you control whether/how copies are made (since there's no assignment, copying would have to be by a subprogram that you provide). (Another way to control copying is to derive privately from Ada.Finalization.Controlled and override Adjust...) 2b) Declare the public view with unknown discriminants, e.g. type Foo_Type (<>) is private; Then, whether the full view actually has discriminants or not, the only way for the client to declare an object of the type is with an initialization expression (because the client' has no other way to constrain the object!). In your package, you can declare "constructor" functions that return an instance of the type, initialized correctly, and perform any side-effects associated with creation of the object. The only way a client can create an object is to call one of your Create functions, E.g., X : Foo.Foo_Type; -- Illegal! Must be constrained... -- This works: -- X : Foo.Foo_Type := Foo.Create (-- blah, blah, blah..); (Another way to control initialization is to derive privately from type Controlled or Limited_Controlled in Ada.Finalization and override Initialize, but that only gets you a "default constructor", i.e. with no parameters). If you make the public view limited *and* with unknown discriminants, then the client can't declare an instance of the type at all! It can only set up functional "plumbing", because your package owns all the instances. 3) If none of the above can work, then you know you have a type whose full view belongs in the public part of the spec! :-) Have fun! Mark Lundquist Rational Software Sent via Deja.com http://www.deja.com/