Re: Unix and OO Avoidance
From: peter_douglass (baisly_at_gis.net)
Date: 01/04/04
- Previous message: Ravi Shankar: "Re: Regarding a protocol decision"
- In reply to: Robert C. Martin: "Re: Unix and OO Avoidance"
- Next in thread: Universe: "Re: Unix and OO Avoidance"
- Reply: Universe: "Re: Unix and OO Avoidance"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sun, 4 Jan 2004 15:34:27 -0500
Responding to "Robert C. Martin"
> On Sat, 3 Jan 2004 18:33:43 -0500, "peter_douglass" <baisly@gis.net>
> wrote:
Before I respond to the details of RCM's post, I want to restore the context
of my comments.
BobS > Another problem seems to be that a poor
BobS > programmer can have much more impact
BobS > with OO methods. With functional methods
BobS > and languages the impact of those
BobS > people seemed to be much more limited.
BobS > You could draw a line around
BobS > their work, cut it out and replace it.
PeterD > I definitely agree with that point. One poster
PeterD > on this news group, several years ago
PeterD > compared OO to dynamite. I.e. something
PeterD > dangerous to let into the wrong hands, but
PeterD > useful in some situations (such as mining) nonetheless.
DirkR > Huh, any arguments for this? Speaking from my own
DirkR > experience I would assume that exactly the opposite is true.
DirkR > Having a proven OOA/D model makes is much
DirkR > more easier for poor (maybe unexperienced is a
DirkR > more suitable word) programmers to get involved
DirkR > in the implementation of some subsystems. Maybe
DirkR > the programmer is messing up with the
DirkR > implementation, but at least you know that he must
DirkR > conform to the interfaces. So to me it seems clear
DirkR > that decoupling and implementation hiding allows
DirkR > for later replacement of bad code with less maintenance
DirkR > costs, or am I missing the point?
DirkR > So with OO methods you can draw a line around
DirkR > their work, it's the interface! What would the line
DirkR > be in a non-OO project?
I feel the need to restore the context because in quite a few places, RCM
erects straw men, only to knock them down. The actual points under
discussion are:
1) Whether functional methods and languages limit the negative impact of
bad programmers,
2) Whether OO methods and languages *permit* a bad programmer to have a
large negative impact.
No-one is making the claim that non-OO methods *in general* restrict the
negative impact of unskilled programmers.
Nor is anyone making the claim that skilled OO practitioners cannot avoid
the pitfalls discussed.
*****************
[context]
DirkR > Maybe
DirkR > the programmer is messing up with the
DirkR > implementation, but at least you know that he must
DirkR > conform to the interfaces.
> >1. Programming to interfaces is used not only in OO, but also in most
> >structured programming. When work is divided amongst a group of
developers,
> >it only makes sense to agree upon interfaces beforehand.
> True. However the word "interface" has a very different definition in
> the OO context, than it does in the structured context. In an OO
> project the interfaces are dynamically polymorphic, whereas in a
> structured project they are static.
As an aside I point out that in RCM's linguistic framework, OO == dynamic
polymorphism. This implies that non-OO code cannot have dynamic
polymorphism. However, since all varieties of polymorphism except
polymorphism based upon inheritence are available in one or another language
supporting structured programming, in your linguistic framework, we must
have a category of Object Oriented Structured Programming.
RCM has been chided many times in the past for demonstrating a lack of
understanding of polymorphism. Although he may reply to the above paragraph
with "Of course there is Object Oriented Structured Programming", my guess
is that his original comment was rather inspired by a very narrow view of
polymorphism. Robert, I find it very surprising and sad that you do not
bother to refine your positions more carefully, given that polymorphism is
the keystone to your definition of OO.
Robert, is the following scheme code OO your view?
(define foo
(lambda (x)
(case
( (number? x) (do_number_stuff x))
( (string? x) (do_string_stuff x))
( else (do_unknown_type_stuff x))
)))
Is it polymorphic? Does it dispatch on types at run-time?
Enought of the aside. Lets address Dirk's question. Programming to an
interface as one means of "drawing a line" around code in OO projects. Is
the same available to non-OO projects? You (RCM) say that interfaces in OO
projects are different from interfaces in non-OO projects, specifically, OO
interfaces have dynamic polymorphism. I fail to see how this impacts the
issue of "drawing a line around the code". Perhaps you can elaborate.
> >2. One of the mosts important aspects of the behavior contracts involves
> >changes to global state. In languages designed to support structured
> >programming, global state tends to be tightly tightly controlled. The
> >default assumption is that no subunit of code may cause changes to state
> >outside of its local variables. If it is the responsibility of a subunit
to
> >make changes to state outside of its scope, that responsibility is made
> >explicit in the contract. (For example by making a call pass a reference
to
> >a data-structure, rather than a copy of that data-structure).
> Controlling the global state of the system is good practice. This
> applies both to OO and non-OO systems. The techniques in both kinds
> of languages are the same.
In RCM's linguistic framework, Haskell must be defined as an OO language,
as it supports dynamic polymorphism. Thus in that framework, OO is
compatible with pure functional programming, that is, programming without
mutable state. It therefore becomes trivially true that the method of
controlling state with functional programming is a technique available to OO
programmers.
While this may be true in RCM-speak, in the vast body of literature on OO,
changing the state of objects plays a central role. Certainly, when we look
at languages (and you write "the technique in both kinds of languages...),
most OO languages do not prohit mutable state.
> >In languages supporting OO, although state is local to each object,
objects
> >themselves are global.
> It's hard to tell what you mean by this. Clearly not all objects are
> accessible to all other objects.
Clearly not all objects are accessible to all other objects. So you are
correct that you do not understand my meaning.
An object represents a piece of global state. Not all other objects will
have references to any particular object. But if the code in object A
includes a method call to object B, and that method call changes the state
of object B, then every other object which subsequently accesses object B
may obtain results based upon that new state.
> >Thus any object may invoke a state changing method
> >upon any other object to which it has a reference.
> True, just as in a structured program any function may change any data
> structure to which it has a reference. Do you see a difference?
Since I may write structured programs in pure functional languages, I must
disagree with your assertion. In pure functional programming languages, no
function may change any data structure, whether or not it possesses a
reference to that structure.
Do I see a difference? That depends upon whether you broaden the discussion
to ask whether all structured programs have a tight discipline on data
mutation. No they don't. But I do see a difference between how the vast
majority of OO languages permit mutable state and the way pure functional
languages prohibit mutable state. I also see a difference between the way
hierarchical languages like Pascal impose a discipline on the flow of
references, (and consequently on mutation) and the way non-hierarchical
languages both OO and non-OO (like C) impose little discipline in this area.
> >Thus in an language
> >supporting OO, the correct behavior of the program may (and I'm not
claiming
> >this is the *intent* of OO) be very sensitive to the order in which
method
> >calls are made.
> This is also true in a structured program. If one calls 'close'
> before one calls 'open' the program won't work very well. If one
> calls 'close' before the last 'write' the program won't work too well.
> This is not an issue that is particular to OO, or that is more serious
> in OO. OO programs are no more sensitive to calling order than
> structured programs are.
The example you site "open, close, write" involve changes to state external
to the program, i.e. i/o devices and the "real" world. Naturally, this must
be ordered properly. If you print "a" and then "b", it is not the same as
if you first print "b" and then "a".
But your argument is this. Since all languages are sensitive to changes in
order, then all languages are equally sensitive to changes in order. This
is a logical fallacy, and furthermore, the conclusion is false. Not all
languages are equally sensitive. In Haskell, all non-monadic code is immune
to changes in evaluation order. In fact, except in monadic code, and in
cases where the coder expicitly annotates evaluation order for efficiency
reasons, the actual order of evaluation is irrelevent to the final results,
unknown to the programmer, and may change from one compiler to another.
> >A program in such a language, may take on a striking
> >similarity to a multi-threaded application, where the behavior of one
unit
> >may interfere with the intended sequence events in another unit.
> Programs in non-OO language can exhibit the same tendency (i.e.
> co-routines). OO programs are not more likely to have co-routines
> than structured programs. There is nothing about OO languages that
> makes the flow of control more complicated.
The claim was not that OO languages "make the flow of control more
complicated". The claim was that OO languages "allow" the control of flow
to be complicated, or "seemingly multi-threaded". Please remember that the
point in question was whether OO languages are powerful but dangerous in the
hands of the unskilled.
> >H.S.
> >Lahman, will argue that one of the design rules for good OO is to write
code
> >which works in spite of changes to the sequence of events.
>
> That's one of the goals for software design in general. And it's one
> that must always be compromised. All programs have state changing
> functions, and those function have to be called in the right order.
> We try to minimize this in both OO and non-OO contexts. There is
> nothing about OO that makes minimizing it harder.
All programs which have output, must change the state of the world. Beyond
that, the "quantity" of state change in a program can vary from "nothing
else changes" to having side effects everywhere.
If OO programmers "minimize" state changes, they would be functional
programmers, and their objects would be functional objects without mutable
state. There are functional OO programmers, and in your language, Haskell
may be an OOPL. But to claim that "We try to minimize this in both OO and
non-OO contexts" is quite untrue. I have yet to see a program of yours
which "minimized" state change.
As for whether typical OO languages make minimizing state changes harder,
the lack of proper tail-recursion optimizations make functional programming
in OO languages quite difficult.
> >While this is an
> >appropriate design rule, it is very easy for someone who is not skilled
in
> >OO to write code which contains many sequence order dependencies, and is
> >consequently very brittle.
> It has nothing to do with OO skill. It has to do with general
> programming skill. The skill that prevents a structured programmer
> from creating order dependencies will also prevent order dependencies
> from being created by an OO programmer.
The same skill which allows an OO programmer to avoid sequence order
dependencies in an OO language will allow that programmer to avoid sequence
order dependencies in a typical procedural language like C. In Haskell,
that particular skill is mostly unneeded.
> >3. I myself have experienced working on an "OO" project in which
sequence
> >order dependencies made the code an absolute nightmare. Slight changes
in
> >one class would break behavior in other classes. I know this isn't how
it
> >is supposed to work. But it is certainly how it *can* work, and how it
does
> >work in unskilled hands.
> I have personally worked on procedural projects that exhibited the
> same sensitivity. You are right, it's not supposed to be that way.
> In my case the designers were unskilled novices. I suspect the same
> is true in your case -- I don't see how it could be otherwise.
Agreed. Agreed. and you are right.
> >Again, the global nature of objects in OO languages means that a
programmer
> >can alter global state in undisciplined ways.
> This statement makes no sense to me.
I'm sorry to hear that, though I'm not terribly surprised.
> >DirkR > So with OO methods you can draw a line around
> >DirkR > their work, it's the interface! What would the line
> >DirkR > be in a non-OO project?
> >One can restrict the side effects available to a developer by restricting
> >the data structures which he or she can modify, by for example passing
them
> >by value instead of by reference. The "line" around a programmers work,
is
> >in some procedural languages extremely well defined.
> You can restrict the side effects available to a developer by
> restricting the objects that he or she can modify, by for example
> passing them as const, or passing an interface with only the
> appropriate methods declared, or passing a restrictive adapter.
> However, the best way to make sure that a programmer doesn't change
> program state in an undisciplined way is to make sure that all the
> programmers understand how the system works, and have them review each
> other code carefully.
Ah, you see your last line gives away the whole argument. The language does
not enforce the discipline, rather the programmers must be skilled enough to
employ the discipline. And if they don't? That is the the core of the
issue.
> In an OO project, you can draw a line around a module that is both
> extremely well defined and virtually impossible to cross. Indeed, the
> drawing of such lines is what OO is all about.
The debate is not about what a skilled OO programmer can do in an OO
project. The debate is about what an unskilled programmer can do in [to?]
an OO project.
--PeterD
- Previous message: Ravi Shankar: "Re: Regarding a protocol decision"
- In reply to: Robert C. Martin: "Re: Unix and OO Avoidance"
- Next in thread: Universe: "Re: Unix and OO Avoidance"
- Reply: Universe: "Re: Unix and OO Avoidance"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|