From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Subject: Re: many set/get member functions in a class?
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Date: Tue, 21 Jul 1992 16:10:44 GMT

In article <14fl44INN6rn@darkstar.UCSC.EDU> ericg@ucschu.ucsc.edu (Eric Goodman) writes:
>To add another voice to the discussion:
>
>I will refrain from direct quoting as many other quotes are floating 
>around. It seems to me that two different issues are being discussed:
>
>On the one hand, the argument that public variables are useful seems to 
>focus primarily around the concern of code breaking due to 
>reimplimentation of a class. On the other hand, the argument for "allowing 
>the semantics to change" is an issue of code extensibility.

	It is an issue of *extensibility* as opposed to *mutability*.
If you tack on an extension to something, and use it, then I'm
not using it, so you can do it privately without upsetting me.

	If you *mutate* existing code you should be able to do it
privately only if it *does not change the meaning of my programs*.
Otherwise, you should do it publicly in a way that forces me
to reexamine my program and perform the corresponding mutations.

>
>The first case (avoiding code breaking) seems to me to be more an issue of 
>the "release version" of tools. If I am writing an interface and I lend it 
>to maxtal to use in his code development and then I subsequently change 
>the semantics of the class(es), I agree that I have broken my contract 
>with him unless I warn him that the class I gave him was "under 
>development". Otherwise he has no way to know that I am changing the 
>meaning of the class and therefore no way to know that I broke his code ON 
>PURPOSE by changing the meaning of the class. 
>
	Yes.

>However, I DO NOT accept this as a good reason to write using public data 
>members. 

	There is no way for the compiler to enforce the excellent
sense of ethics you have presented above --- except in ONE case:
that of public variable. You CANT change the meaning of a raw
public variable on me except by changing its access or removing
it, and in either case the COMPILER tells me. Just as if
you changed the interface, which, of course, you have.

	That isnt an argument in favour of using public
variables per-se. The argument is that IF there is some
unconstrained variable, you might as well actually use
a variable for it, SINCE it provides this guarrantee,
UNLESS there are other good reasons for NOT using a public variable,
which there often are.

	In many programs I write there are several raw C-style
structs floating around, and I'm not ashamed of them.
In fact, I usually make a point of providing them no virtual
members, in fact, often no members other than a constructor.

	Of course, I often use them as a base class for another
class that hides the whole struct :-)

>IF I give him code and say "that's it, I may change the 
>implementation but not the semantics" I must stick by that statement (from 
>a moral point of view - in real life I'd just go ahead and break his code 
>:-) ). 
>
>Let me work with the point and ConstrainedPoint example we had before 
>(sorry, I lost the post, so can't quote it). Maxtal argues that when the 
>set_xy function is modified in the constrainedPoint that I am breaking his 
>code. I completely disagree. If I define a virtual function in the class I 
>give him (point) I have CLEARLY stated that I may make a class derived 
>from class point WITH DIFFERENT SEMANTICS (that's the whole point of using 
>a virtual function). 

	I think we quibble about the meaning (no pun intended :-)
of "semantics".

	If you have a virtual function 'no_legs' in an animal
class, and for DOG you give 4, and for CENTIPEDE you give 100,
you have NOT changed the semantics. The semantics is
"returns the number of legs on this type of animal".

	If, on the other hand, you return the number
of eyes instead, you have changed the semantics.

	By this definition, you should NOT change the semantics
of a virtual functions : ESPECIALLY NEVER a virtual function.

	As noted in another post, what you leave *unsaid*
in the spec is just as important as what you specify, it is
ONLY in the area of bits unspecified that you have room for
change.

	For example, an animal might have an odd number of legs.
BUT if your spec said "return no of legs, which is always even",
then you may NOT return an odd number of legs. OK?

>If I overload a non-virtual function then his code is 
>unaffected because my constrainedPoint s will be cast to be normal points. 

	Yes.
>
>Maxtal goes on to state that if I change the way set_xy works I should 
>have to examine all accesses to make sure they are valid. The compiler 
>already requires that all instances be examined. In case it's unclear why 
>I must look at all instances its because currently all my code says "point 
>A,B,C;". To make use of the new code I MUST change all these lines to 
>"constrainedPoint A,B,C;" so I am ALREADY looking for all point instances, 
>and Maxtal's condition is met, right? 

	Not if 'set_xy' is a virtual function and I have references
to point which might include ConstrainedPoint. 

	You will note in my previous posts I am against 'set' type
functions in general, this is a perfect example. You should
use a CONSTRUCTOR to set the values. Now you can make
'get_x' and 'get_y' virtual because the semantics of *those*
functions doesn't change. 

>I understand that this is not quite 
>the same as looking at all accesses, but it is (IMHO) close enough.

	For actual objects, yes this is enough. You change
A from one type to another, you know that 'A' is to be further
examined. It is not enough where the are references though.
>
>The difference here is the contract between a programmer and a 
>"beta-tester" (someone who's using under development tools) and someone 
>who is acting as a "client" (using decided upon classes). 

>To cripple 
>extensibility (that is how I look at using public data members) in order 
>to help beta-testers is not a good trade off. 

	Well, it is hard to disagree when you say 'cripple' :-)

>Perhaps while under 
>development a class could use public data members, but once "out-the-door" 
>all data members should be hidden and updates should come as derived 
>classes only precicely to avoid the problems that maxtal points out. 
>

	Ah, 'protected' data members could be thought of
just as for 'public' ones. 

	INDEED, private data variables are just the same. If you want
to make the implementation flexible, DONT use a private variable
for EXACTLY the same reasons as above (except the contract here is
at a different level, the same principle applies).

	Instead, you should use a pure virtual function
returning the same type as the variable. (In other words,
everywhere you argue for get_set instead of a varaible,
the argument applies at each of 'public', 'protected'
and even 'private' access levels. There are then three levels
of defering implementation detail!!

	Obviously this has to stop somewhere: it is a programmer
decision whether to make the variable public, protected,
private, or pure virtual (in which case the variable is
in a derived class).


>
>Eric Goodman
>Humanities Computing
>UC Santa Cruz
>ericg@hum.ucsc.edu  or  @ucschu.bitnet


-- 
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
	Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
Newsgroups: comp.lang.c++