|
![](/i/fill.gif) |
Warp wrote:
> Your definition of object-oriented programming may vary, but in my view
> data hiding, ie. modularity, is an integral part of OO programming.
It's pretty easy to fix in LISP if you really care - just make all your
local names gensyms. (If we're still talking about minimal support for lots
of paradigms, you could do this with some pretty simple macros, methinks.)
CLOS doesn't do this, because people who use LISP are usually pretty good
programmers.
> If the
> internal structure of the object is exposed to the outside, you lose most
> of the benefits of modularity.
Like, in unsafe languages, where a stray pointer can change private
variables without going thru the class methods? :-)
By this factor, I know of almost no actual OO languages besides Smalltalk
and Ada. (And Ada has OO features without being what I'd call an OO
language.) And I'm not sure you can't cast pointers inappropriately in Ada,
either. I'll look it up some day when I'm bored. :-)
C# and Java both have reflection that let you get to private members from
outside. C++ not only lets you return pointers to private members (which
isn't particularly bad in *my* opinion, see below, but you might disagree)
but also allows unsafe (in the technical sense[2]) access to private members
via undefined operations. It's pretty trivial to bypass all the modularity
in C++ since you need to be able to see the class declarations of the
private parts in order to access the class[1]. Python has the __dict__
element (et al) even if you had private variables. Pretty much anything
designed so you can serialize it has external access to private members.
> I think that the typical impossibility or difficulty in data hiding in
> languages which do not have specific support for modularity is a sign that
> the "OOP" is, after all, just a kludge.
Now, ya see, I see the point of modularity is to let me reason about the
code. If I have a private integer X, and the only things I set it to are 0,
1, or 2, then I should be able to have a switch with those three cases and
never miss one. Or, for a better example, if I have a buffer, and my class
is the only thing that writes to the buffer, I can ensure I never have a
buffer overflow. This isn't the case in C++ any more than it is in LISP or
Python. The only difference is, in LISP it's much harder to break by
accident. I don't see the advantage of making variables private if the
privacy isn't enforced well enough to give me more guarantees about the
program's execution. It's like having type declarations that aren't checked
at compile time or runtime - what's the point?
It would seem to be no harder to track down a bug caused by someone
accessing a private variable in a LISP object inappropriately than it would
be to track down someone overflowing a public array and clobbering a private
member in C++, especially since in LISP you'd actually have the name of the
private member somewhere in the source code module causing the trouble.
What do *you* think modularity is good for, that simply saying "stuff that
starts with an underline is private to the class" isn't adequate? I'm
seriously asking, because I'm wondering if I'm missing something.
[1] For example, you could declare an identical class with a different name,
except with all the privates public, then cast a pointer to the private
class into a pointer to the public class. Don't even need to depend on
compiler-specific knowledge about element layout and such. Or just declare a
child class that is happy to change any of its private variables.
[2] "Unsafe" means there are features with undefined behavior which may
affect the future state of the program, such that you can put values of the
wrong type into variables. That is, you can put values that don't belong to
the type into a variable of that type, or access values inappropriately
(such as accessing private variables from outside the scope you're supposed
to access them from).
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |