Python is wierd!

Alex Martelli alex at magenta.com
Thu Jul 27 16:06:34 EDT 2000


What "Mark Baker" <mbaker at 0x7a69.net> is writing today in
news:65Pf5.329$SM4.36312 at nntp2.onemain.com...:

> looking at friend not from within C++, but from within an abstract view of
> what it does.

Sure.  And what it does, is enable C++ designs to split a component's
functionality among several, closely-coupled classes -- i.e., implement
the concept that is variously called "component", "module", "package" --
while maintaining its encapsulation concepts with respect to anything
that is _outside_ of the package.

What Mark is basically claiming today is that this same purpose is better
accomplished in other languages:

> encapsulation. For me, the unit of encapsulation is the object. Whether

[I doubt he means what he says -- that two separate objects, i.e. two
instances of the same, identical class, should be encapsulated/protected
from each other -- he quotes Modula, Oberon, Eiffel, &c, which don't do
that].

> this displays itself at a class level (assuming the language has
> classes...) is relative.
>
> If you enjoy calling a series of coupled classes a component, alright. If
> you'd like to move encapsulation away from an object and instead attribute
> it to a collection of classes, ok.
    [...]
> Would you consider it better to provide fine grained access? That is,
> access to specific portions of a class, than to allow unrestrained access?
> Or do you think that because this isn't a violation to couple a
> class/function, that such granularity is unnecessary? Would this possibley


Contrast with this quote from his original message (in comment to mine),
which prompted me to further respond:

: friend is simply an evil way of violating encapsulation. It's not
analogous to
: modules, packages, or anything else. It simply provides a means of
violating
: C++'s encapsulation (usually for speed purposes, since you should be able

He started out claiming that friend is nothing but an evil way of violating
encapsulation, with nothing to do with modules/packages/"anything else" (the
term both Lakos and Martin use, and which I like although it's overloaded in
closely related domains, for this 'anything else', is *component*).

Now, and without ever specifically admitting that what I just quoted was
horribly wrong, he's changed from that position to friend being useful
_exactly_ for such purposes -- but there being better ways in other
encapsulation-oriented languages.

I'm not particularly motivated to debate various languages with Mark, nor
what are better or worse ways and means to enforce encapsulation; I do not
believe this would particularly illuminate the subject, i.e., whether
Python is 'wierd' for choosing not to enforce it (specifically, as in
the observation that started this sub-thread, by making it most natural
to use module-defined functions in lieu of class-static ones).


I *AM* quite keen to show that Mark's untenable position -- that friend has
nothing to do with component encapsulation -- has been quietly dropped.
friend is _ABOUT_ divvying functionality up between classes in a component,
while maintaining that component's encapsulation wrt other components.  It
has just about nothing to do with speed, everything with PRESERVING the
right kind/level of encapsulation.

And *this* is very important, because it helps to show what the right
kind/level of encapsulation IS -- the kind advocated by Lakos (which
in is view is maintained by a combination of C++'s encapsulation support,
including, crucially, "friend", and coding conventions such as "one
physical exposed/published header-file per component"), the kind most
encouraged by Python (without substantial enforcement, but mostly
through conventions), &c -- *component-level* encapsulation (in Python,
"component" being a module or package; in C++, a consistent set of
classes and functions declared in a single header-file; in Java, the
explicit language concept of package, including default accessibility
level, often called, guess what, 'friendly'; ...).

Languages vary widely in the amount of enforcement they attempt to
do regarding encapsulation (just as for other kinds, such as "type
correctness") -- from Python's "by-convention-only", all the way
to Eiffel's extremely rich, very-fine-grained access-control.  C++'s
"friend" is just one point along this continuum, as is Java's idea
of adding just one extra accessibility level to C++'s three, to be
specifically devoted to access by the package's other classes.  It
is, I feel, quite unadvisable to call any of these design choices
"evil" (or, for that matter, "wierd" -- or "weird", even:-).  It
does seem established by several languages' experience that:
- encapsulation can be useful, particularly in large projects;
- enforcement of it may be so crucial as to devote vast language
    machinery to it (Eiffel's stance), or so minor as to devote
    none (Python's stance), or of middling importance, deserving
    some modest amount of language machinery (C++'s and Java's);
- the crucial level for encapsulation in a large project is the
    component/package/module, not the single class, or class
    hierarchy -- even Eiffel, which is so utterly class-centric,
    amply recognizes this fact in its language-machinery.


In fact, my favourite approach to software development (and not
mine only -- it's definitely the growing trend!-) is to center
it on components, ideally exposing specific functionality to each
other through a dedicated language for interface definition (or
semantically equivalent meta-data).  But header-files will do,
if I'm using C++, and Python's modules and packages will do just
as well, if I'm using Python; the advantage of a dedicated IDL,
or meta-data, comes chiefly in a cross-language environment,
although it typically enforces encapsulation _where it really
matters_ (at the component's interface), which can be a nice
side effect too.


Back to 'friend' and how misguided it is to see it just as
a way to _violate_ encapsulation, rather than _enhancing_ it --
let me offer an analogy -- and one that not even Mark can claim is overly
friendly to 'friend'.  Say that I was discussing various kinds of loops,
mentioning, among several other languages, how in FORTRAN IV they are
implemented in terms of IF and GOTO.  And some wiseguy perks up and
rebuts that "GOTO is simply an evil way of violating control flow.  It's
not analogous to WHILE, DO, or anything else.  It simply provides a
means of violating FORTRAN's control flow (usually for speed purposes" &c.

Would I be "naive" to infer from this that the wiseguy doesn't understand
FORTRAN IV, and/or GOTO, and/or loops?!  Maybe, I guess -- it IS quite
possible that, while being highly experienced in each of these areas, the
wiseguy has just been partaking too richly of mind-affecting substances,
or is otherwise motivated to post assertions he knows to be false.  But,
I don't mind being naive in this sense: that of assuming, until and unless
forced to conclude otherwise, that people mean what they say, have no
dark, deep, hidden agenda, and are just stating their best understanding
of whatever issue is being discussed.  Thus in particular, that when they
counter my assertion:

"grouping by-module is more productive than by-class (the class is not the
natural unit of encapsulation, an issue that is also acknowledged by the
package concept of Java and the friend keyword in C++)"

with a blunt statement that friend has nothing to do with grouping by
module (package, component, ...) rather than by class, I will assume
that they don't know what they're talking about, rather than the only
alternative, assume they're deliberately lying -- just as if they
stated that GOTO has nothing to do with control-flow structures.


GOTO is, obviously to anyone skilled in the art, THE way that control
structures (e.g., loops) are implemented in a language lacking other
dedicated means for the purpose, such as FORTRAN IV.  It may well be
that control-structures are important enough to warrant more syntax
superstructure (I believe they are), which some languages (most modern
ones) offer in GOTO's stead, but that can never justify assertions
that GOTO's are not ABOUT control-structures.

friend is, obviously to anyone skilled in the art, THE way that
component-level encapsulation is implemented in a language lacking
other dedicated means for the purpose, such as C++.  It may well be
that encapsulation is important enough to warrant more syntax
superstructure (I believe it is not), which some languages (Java,
Eiffel, &c) offer in friend's stead, but that can never justify
assertions that friend is not ABOUT component-encapsulation.



Alex






More information about the Python-list mailing list