Newsgroups: comp.lang.smalltalk
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!news.mathworks.com!gatech!news.sprintlink.net!noc.netcom.net!netcomsv!uu3news.netcom.com!netcomsv!uucp3.netcom.com!medicus!billf
From: billf@medicus.com (Bill Foote)
Subject: Re: "Private" methods
Message-ID: <1995Jun1.182047.8501@medicus.com>
Organization: Medicus Systems Corp.
References: <3qga8f$d2t@pipe6.nyc.pipeline.com> <3qjbvq$24t@ocean.CAM.ORG>
Date: Thu, 1 Jun 1995 18:20:47 GMT
Lines: 95

In article <3qjbvq$24t@ocean.CAM.ORG> vbykov@CAM.ORG (Vassili Bykov) writes:
>mzr@nyc.pipeline.com (Moshe Rubak) writes:
>
>>Hi, 
>> 
>>I have noticed that some people find the lack of "private" (C++
>>[...]
>>---------------------------------------------------------- 
>>rows: integer 
>>    "private - set number of rows" 
>> 
>>    (self sender class = self class) | 
>>    (self sender = self class) 
>>        ifFalse: 
>>            [Error signal: 'private method -  Not to be used outside
>>class']. 
>> 
>>    rows := integer. 
>>[...]
>
>WHAT FOR???
>
>What you describe is not quite what is in C++.  C++ has a static typing
>and member access rights checking at compile time. 
>  <...>

    <getting on my SE soapbox...>

What for?  Why, to enforce a design decision at runtime, because the language
doesn't let you do it at "compile" time.  This general strategy (of using
run-time checks to detect inconsistencies) is used in a number of other
languages -- look at <assert.h> in the C/C++ world, the Object>>ASSERT: 
method (in Digitalk Smalltalk, at least), and in Eiffel, look at
pre/post conditions, invariants, and the Check instruction.

Typically, you want a way to eliminate such assertions from your program
at application deployment time -- With C/C++ you do this with -DNDEBUG,
and with Eiffel by setting a compile-time option.  I assume that a similar
thing is possible with Object>>ASSERT:  -- I guess at worst one could find
all callers of it and get rid of them prior to deployment, but it doesn't
seem like it would be too hard to automate this (as a part of image
stripping, for example).  Stripping assertions at deployment time can
be important -- if you know that you don't have to pay for the assertions
at (client) runtime, you're more likely to use them, even for tests that
are somewhat expensive.

Assertions can be a *very* powerful technique for detecting bugs early, and
close to the source.  I think that Bertrand Meyer nicely expressed it...
From Eiffel, The Language, page 132:

    Assertions and the associated variant facility express correctness
    requirements on software texts.  This has an interesting consequence
    on any attempt at defining the semantics of assertions:  in the execution
    of a correct system, every assertion will always be satisfied at the
    times when it has to (...).  So in theory it should not be necessary
    to define the semantics of asssertions evaluation:  for a correct class,
    the effecct of evaluating an assertion is irrelevant, since the value
    is always the same!  This may be called the paradox of assertion
    semantics.

    The paradox is only theoretical.  In practice, short of proofs as
    discussed above, one must often accept the prospect that a system may
    contain errors -- may not be correct.  Then assertions provide crucial
    help in detecting these errors and suggesting corrections.  By
    directing the run-time system to evaluate assertions and variant 
    clauses, and to trigger an exception if it detects a violation, you
    check the consistency between what the software does (the routine
    bodies) and what you think it does (the assertions):  you let the
    tools call your bluff.  This gives a remarkable tool for debugging,
    testing and maintaining software systems.

Over the years, I've found assertions to be an excellent tool during
development and QA, and enforcing private semantics is IMHO a
completely appropriate use of them.  I don't think that I'd do this
on *every* "private" method (it would get a bit tedious!), but where
appropriate, it seems like a great idea!

To get back to the original code snippet, might I suggest the following:


    rows: integer 
	"private - set number of rows" 

	self ASSERT:
	    (self sender class = self class) | (self sender = self class) .
		" Enforce privateness of this method ".

#isKindOf: can, of course, be used to enforce protected semantics.  The
"| (self sender = self class)" is important to duplicate the C++ private
semantics of allowing class methods to call private instance methods.
--
Bill Foote                | Adde parvum parvo magnus acervus ecrit.
billf@medicus.com         | [Add little to little and there will be a big pile]
Medicus Systems           |    -- Ovid, via Frederick P. Brooks, Jr.
Alameda, CA USA           |
