Steven D'Aprano a écrit :
On Sat, 17 Jan 2009 20:49:38 +0100, Bruno Desthuilliers wrote:
Russ P. a écrit :
(snip)
Why leave to
coding standards and company policy what can be encoded right into the
language?
Because human are smarter than computers.
That's an awfully naive statement. It's a sound-byte instead of a
reasoned argument. We're smarter than computers?
Obviously and definitively, yes. Not that we are that smart - it's just
that computers are totally stupids. The differences between a human and
a computer are that
1/ a human can eventually DWIM.
2/ a computer can do what is has been told way faster than any human
The first point is being smart. The second is being fast. Not quite the
same thing !-)
Then why are we
programming in languages like Python instead of directly in machine code?
Why can optimizing C compilers make more efficient code than the best
human assembly language programmers?
Because :
1/ this is something that can be solved by heavy computations
2/ these computations can be programmed
3/ these compuations would just take too long for a human being to do
manually
Humans and computers are smart at different things.
s/smart/good/g
Why leave to humans (who are known to err) what can be automated
relatively easily? Isn't that what computers are for?
Error is human. For a real catastrophic failure, it requires a computer.
Oh rubbish. That's a sound-byte invented by nervous technophobes scared
of computers.
Nope, that's a computer-user joke.
All those "setters" and
"getters" are a kludge. I think Python "properties" are a major step
forward here. Just for fun, I checked to see if Scala has properties.
Guess what? Not only does it have them, but they are generated
automatically for all member data. That's even better than Python
properties!
Oh yes ? "Better", really ? So it's better to have a language that
automagically breaks encapsulation (requiring an additionnal level of
indirection) than a language that do the right thing by default ? I'm
afraid I missed the point ???
You certainly do. How do properties "break" encapsulation rather than
enforcing it?
Properties by themselves are not the problem, quite on the contrary - as
you say, they actually help wrt/ encapsulation. What breaks
encapsulation is *automatic generation* for properties for *each and
any* implementation attribute. Might as well just makes them all public
attribute then.
As I said before, enforced encapsulation may not be appropriate for
every application, but it is definitely appropriate for some.
No. It is appropriate for dummy managers hiring dummy programmers. The
project's size and domain have nothing to do with it.
Let me try to be very clear here. We are dealing with two separate but
related issues. The first is whether data hiding should be added to
Python.
No need to add it, it's already there : every name that starts with an
underscore is hidden !-)
That's not hidden. It's there in plain sight.
Once again, I'm afraid you missed the joke - despite the smiley.
Whether it can be added without screwing up the language, I don't know.
If not, then so be it. That just limits the range of domains where
Python is suitable.
That's just plain stupid.
No it's not. It's *practical*. There are domains where *by law* code
needs to meet all sorts of strict standards to prove safety and security,
and Python *simply cannot meet those standards*.
Oh, sorry. I was talking about *technical* issues, not about legal ones.
IANAL...
(snip)
I like to use the example of the flight software for a large commercial
transport aircraft, but many other examples could be given. How about
medical systems that control radiation therapy or chemotherapy? How
about financial systems that could take away your retirement account in
1.5 milliseconds. Or how about the control software for the strategic
nuclear arsenals of the US or Russia? When you consider the sea, air,
and land-based components, I'm sure that's one hell of a lot of code!
And ? Such systems have been written (and quite a lot are still running)
with languages way more permissive than Python. You know, languages like
C or assembly.
Yes, and it is *hard* because the programmer has to worry about data
hiding *on his own*.
Nope, it's hard because C and assembly are very low-level languages
where you have to micro-manage each and everything. This has nothing to
do with data hiding (unless you count memory management as data hiding ?)
One of my friends has worked for many years programming some pretty high-
powered banking software. Their approach is to move data-hiding into the
database, or the operating system. Cobol doesn't enforce encapsulation,
but the database and OS certainly do, with a permissions-based approach.
Guess what ? Whatever the language (Cobol, Java, Python, or even VB),
chances are such an application would be written using a RDBMS (not even
addressing the point about OS).
Speaking of banking software, consider a typical banking application. It
may have dozens or hundreds of programmers working on it. It's too big
for any one person to understand all of it. Once deployed it may
potentially have access to hundreds of billions of dollars of other
people's money. Don't you imagine that one or two of these programmers
might be tempted to skim a little off the top?
There have been some major failure on such applications written with
"serious" languages like Java. Know the sooo common "catch-all
do-nothing exception handler" idiom in Java ?
Data hiding is a good way of making sure that the guy writing the front
end can't just turn of the audit trail and transfer $60,000,000 into his
bank account.
Man, you can't be serious ? Tell me this is a joke ?
Until you understand that *no technology is idiot-proof*,
you'll get nowhere in "software engineering".
I suspect that Russ has got a lot further in software engineering than
you have.
Most of what is actually labelled as "software engineering" is snake
oil. They're trying to sell you silver bullets. Now where's the werewolf?
No technology is failure proof. But there's no reason in the world why
most technology can't be idiot-proof. Televisions are idiot-proof,
because they protect people from casual mistakes. If televisions were
built according to the Python model, the internals of the TV would be
exposed, without even a cover. All the major parts would be plug-in
rather than soldered in, and there would be no cover over the parts that
were live. Every year, tens of thousands of people would electrocute
themselves fatally (because parts of the TV holds a massive charge for
days after you unplug them from the mains) but that would be okay,
because you never know when somebody might want to pull out the fly-back
transformer and replace it with a six ohm resistor. That sort of dynamism
is important!
Really nice metaphor. Alas, there are limits to what you can do with
metaphores.
(snip remaining)
[...]
An FMS programmer could perhaps
decide to change the parameters of the engine controls, for example.
Why on earth would he do something so stupid ?
I'm sure he'd think he had a good reason. As you said,
"Because sometimes you have a legitimate reason to do so and are ok to
deal with the possible issues."
Maybe other people would disagree whether or not it was a legitimate
reason, or if he was OK dealing with the possible issues.
Perhaps he needed the extra optimization of skipping the getter/setters.
Perhaps he needed it for testing, and somehow one thing led to another.
Who knows?
It is strange that on the one hand you should insist that programmers
sometimes need to mess with internals, and on the other dismiss those who
do as "stupid". Your position is inconsistent.
Nope. My position is quite clear : just don't do something *stupid*. For
a definition of "stupid" that is indeed highly dependant on the context
(which you snipped).
To prevent that sort of thing from happening, the management could
decree that henceforth all "private" variable names will start with an
underscore. Problem solved, eh?
Certainly not. The only way to solve such a problem is to fire this
cretin.
Again, we shouldn't enforce encapsulation and data hiding
s/encapsulation//g
We were talking about language-enforced access restriction. Not about
encapsulation.
because there
are legitimate reasons for breaking it, but anyone who does break it is a
cretin.
Not "anyone". Just those who do it where they obviously should not. And
be sure that anyone cretin enough to mess with implementation *in the
context mentioned by Russ* (context which, once again, you snipped)
would find a "clever" way to do the same (or worse) in any language. You
don't want such a smartass in your team, *specially* for critical stuff.
You have a very strange attitude.
You have a very strange way of handling context.
Besides, it's not very practical. When you fire "the cretin", it has
consequences. Everyone else in the project has to work harder,
My own experience is that firing an obvious cretin from a team leads to
*less* work for the team - because then you don't have to re-read and
rewrite all his code.
[...]
Please educate yourself and learn about why Ariane 5 crashed on it's
first flight, due to an error in a module written in ADA (which is such
a psychorigid language that C++ and Java are even looser than Javascript
in comparison). Perhaps will it light a bulb for you.
Others have already pointed out that the error in the Ariane 5 rocket was
*human* error due to somebody messing with the internals, namely
defeating the compiler's default type checking.
This was *not* an error *in the context* this module was designed (and
tested, QAd etc) for.
I'd just like to ask:
Bruno, were you aware of the cause of the crash,
Yes I was. Else I wouldn't have mention it.
and if not, why did you
raise the issue in the first place?
Because the problem had nothing to do with technology. Only with not
being serious on specs / tests / QA. Hence my point : it's not because a
module has been written using a technology (rightly) known for it's
security and robustness that you can get by with non-technical issues.
Did you think it was a compiler bug
that caused the crash?
Do you think I am a newbie ?
Not
every door needs a lock, but certainly some do.
You only need locks when you don't trust your neighbours.
Yeah, if you live in Nome, Alaska.
Brillant. You obviously failed to understand the differences between
"software engineering" and real life. When it comes to computers, the
only doors I care closing are those which would let someone crack my
computer.
If only there was some way to know which bugs could let people crack our
computer and which bugs couldn't.
>
Anyway, that's your choice. Personally, I'd much prefer my software not
to cause data loss, not to crash, not to DoS me, not to hang, and not to
generate bogus data,
This is a different problem. Please don't mix bananas and screwdrivers.
But FWIW, I never close my car. And, in case you don't know, it's
perfectly possible to access "private" members in Java (and, if you do
have access to the source code, in C++ too).
Yes, but it is more difficult. There's a larger psychological barrier.
It's easier to audit for such access, even in a large project. It
encourages a more careful attitude: "do I *really* need to mess with the
internals, or is there a safer way?". It forces the programmer to *think*
before doing something potentially dangerous.
This is a beautiful dream. Reality is that either the guy is wise enough
to not do something he know he shouldn't without due thinking and
consideration, or he is dumb enough to do something he shouldn't one way
or another.
This is why I wish eval and exec were in a module instead of built-ins.
I do agree they shouldn't be builtins, but mostly because there are too
few real use case for them to be builtins. (well, wrt/ exec, it's a
statement to the problem is a bit different).
Suppose Python worked like this:
class Parrot:
... _private = 'spam'
...
p = Parrot()
p._private = 'ham'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ProtectionError: attribute is read-only from outside of class Parrot
from protection import unlock
unlock(p)._private = 'ham'
p._private
'ham'
>
I don't know if this scenario is even possible in Python,
It actually isn't, at least not without way too much overhead messing
with call stack (and even then...).
"Methods" need to freely access implementation attributes. But Python's
"methods" are just wrappers around plain functions, which by themselves
don't know (and shouldn't need to know) if they where defined within a
class statement or not.
but pretend
that it is.
Ok, let's pretend !-)
Would it be so terrible?
No, I could live with it. Just a question now : how would this deal with
functions defined outside the class statement but used as methods ?
Oh, and please read until the end...
If a particular project wanted to
enforce encapsulation,
s/encapsulation/data hiding/
all they need do is replace or remove the
protection module from their Python installations. (I assume the project
developers aren't *hostile*. If they are, then there's almost nothing you
can do to make the code safe. Encapsulation is about protecting from
accidents, not sabotage.)
InMyArms(tm) !-)
If you wanted to mess with the internals in
your own project, all you need do is import a module.
We could imagine the same scenario in reverse. Python allows getters and
setters, but they're more work,
And more overhead.
and so people just don't use them unless
they really need to.
Which is fine. Well, MHO at least.
Suppose Python offered real data encapsulation,
s/encapsulation/hiding/
but
you had to work to get it:
class Parrot:
... _private = 'spam'
...
p = Parrot()
p._private = 'ham' # allowed by default
from protection import lock
lock(p)._private
p._private = 'spam'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ProtectionError: attribute is read-only from outside of class Parrot
Would that be so bad? I don't think so.
So technically, this means that you'd have an optionel check for
_implementation attribute access outside methods ?
Good news my friend, Pylint already do this (and quite a lot of other
things too...). So wrt/ code reviews, QA etc, the "lack of access
protection" is not such an issue, is it ?
http://www.logilab.org/card/pylintfeatures
"""
W0212: Access to a protected member %s of a client class
Used when a protected member (i.e. class member with a name beginning
with an
underscore) is access outside the class or a descendant of the class where
it's defined.
"""
--
http://mail.python.org/mailman/listinfo/python-list