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.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!samsung!olivea!uunet!igor!rutabaga!jls From: jls@rutabaga.Rational.COM (Jim Showalter) Newsgroups: comp.lang.ada Subject: Re: Pre-condition vs. Post-condition Message-ID: Date: 27 Mar 91 21:34:55 GMT References: <20600091@inmet> <23141@as0c.sei.cmu.edu> <2918@sparko.gwu.edu> <2929@sparko.gwu.edu> <5074@goanna.cs.rmit.oz.au> Sender: news@Rational.COM List-Id: >Perhaps I have completely misunderstood the point of default values for >fields of records. I thought that this, like default values for >omitted parameters, was a dodge to help people cope with the problem >where there is > -- a package P providing a record type or procedure, and > -- a package U using that record type or procedure >and package P is updated to include extra fields in the record type >or procedure, and it may not be practical to update the source of >package U. (In fact, U may be a customer who won't let you anywhere >near their source.) In this practically important but conceptually >limited case, the package provider _can_ determine sensible default >values: "those values which make the new version of the software >act just like the old version". Since I tend to use private types, this argument is spurious. If I am providing a private type in P to which I have added a new field, U is unable to initialize the fields ANYWAY: I must do it for the client, since I am providing the abstraction upon which the client depends. Furthermore, if each U was required to initialize the values in my type, the odds of at least someone screwing it up increase linearly with the number of U's. Finally, consider this case: package Some_Package is type T is private; function Initialize (From_Some_Input : in A_Type) return T; procedure Do_Something (To_This_Object : in out T); Not_Initialized : exception; private type T is record Some_Field : Some_Type; Is_Initialized : Boolean := False; end record; end Some_Package; I, the provider of T, have a field in the record that is used to insure consistency. The default initial value is not something the client can override, so there is no way the client can pass an unitialized value of T to me and get away with it. Without default initialization I cannot ensure this. package body Some_Package is function Initialize (From_Some_Input : in A_Type) return T is The_T : T; begin The_T.Some_Field := Some_Normalization_On (From_Some_Input); The_T.Is_Initialized := True; <====*** return The_T; end Initialize; procedure Do_Something (To_This_Object : in out T) is begin if not To_This_Object.Is_Initialized then raise Not_Initialized; <====**** end if; {do whatever to the object> end Do_Something; end Some_Package; This sort of thing is very useful for applications where data integrity must be ensured (can you think of any where data integrity is NOT important?...). >Now consider the kinds of problems that can arise with default >initialisations, *where the package user knows what the default is*. That's not the issue: default initialization, particularly of private types, is for the benefit of the SUPPLIER, not the client. >One thing which would reduce this temptation would >be to set things up so that a type or subtype can be specified in >a package specification and its default value in the package body. Actually, this is a pretty good idea, at least for visible types (it doesn't matter for private types). -- ***** DISCLAIMER: The opinions expressed herein are my own, except in the realm of software engineering, in which case I've borrowed them from incredibly smart people.