|
![](/i/fill.gif) |
Warp wrote:
> *That* is the beauty of encapsulation.
OK. So you agree that Python also has encapsulation?
Certainly that's one form of encapsulation, and indeed, it's a form also
supported by DLLs, client-server architectures, operating systems,
sandboxes, and many of the other things you said weren't encapsulation.
It's also very useful when designing the original program. But it's more the
modularity part than the data-hiding part. In other words, if you go back to
your original wikipedia link, it's the "language construct that facilitates
the bundling of data with methods operating on that data", not the
"mechanism for restricting access".
You can do that same sort of thing in any language, if you just make clear
what's the public API and what isn't. C does this with FILE* structures, for
example, as well as all the other standard libraries, without any real
features for encapsulation beyond incomplete types. You can also do it in
Smalltalk, which very clearly doesn't have anything beyond documentation to
enforce its modularity.
> Do you really think that the compiler telling you "you must not access
> this member, I refuse to compile it" is not a better way to enforce
> encapsulation than just some documentation that nobody is going to read
> anyways?
Not if you're not going to enforce it the other ways as well.
> If you must have "visible" members in the class declaration for technical
> and/or efficiency reasons, it's better if the compiler offers a tool for
> telling the user "even though you can see this you really shouldn't be
> referencing it directly" rather than relying solely on a comment line.
Sure. What about a naming convention that "comes with the language"? I.e.,
not just a naming convention you made up, but one in common for every single
program written in the language from day one?
> So yes, it's much better if the compiler tells the user he is accessing
> what he shouldn't.
I agree it's better. But since you seem to like binary definitions, and you
don't like me saying "C++ has a little bit of encapsulation but not much",
I'm curious if you think that (say) Python has encapsulation, given that
everyone knows that names with _ are private to the class they're in?
> But where do you draw the line between what is and isn't encapsulation?
I don't make it a binary choice. I say "C has no encapsulation, Python has
very little (more modularity than encapsulation), C++ has a little more than
Python (because the compiler refuses to compile stuff that violates the
language rules), Java and C# have more (because you have to use reflection
or unsafe code), Erlang has a whole bunch (because only bugs in unsafe code
can violate it), and Sing# and Hermes have the most (because they have no
unsafe subsets at all)."
For me, the amount of benefit that encapsulation gives relative to
documentation is nowhere near the amount of benefit that encapsulation gives
relative to guarantees about relationships between code and data enforced by
the language.
> Clearly, a C struct offers no encapsulation. Also, clearly, a faulty RAM
> chip trashing your program's memory doesn't mean there's no encapsulation
> in the programming language. However, where is the line between those two
> extremes, where encapsulation becomes non-encapsulation?
Myself, I'd say when you can accidentally violate encapsulation, you have
poor encapsulation.
> If you call a library offered by the programming language, and that
> library is buggy and trashes your program's memory, does that break
> encapsulation? What if the library calls a system library (such as clib)
> and *that* has a bug which trashes your program's memory? Does that break
> encapsulation? What if instead of a language's own library it's a third-party
> library? What if the kernel has a bug which trashes your program's memory?
> Where exactly lies the line between a bug which trashes the program's memory
> not breaking encapsulation, and doing so? And why?
Those are all breaks of encapsulation, certainly. But those are in the
implementations, not the languages. A buggy RAM chip that randomly changes
values on the stack has nothing to do with whether C++ the language offers
valuable encapsulation.
>> In contrast, C++ has well-defined mechanisms for bypassing the encapsulation
>> that are used as a normal part of programming in that language.
>
> Actually it doesn't. You can read the binary representation of an object
> in memory, but the standard gives no guarantees as to which byte means what.
I don't believe that's true. It certainly wasn't in C.
> The memory layout of objects is completely implementation-defined
Nonsense. Arrays are contiguous. The elements of a structure are all between
&x and &x + sizeof(x). There's lots of guarantees. And I'm pretty sure that
if you have "struct x {int a; int b} y;" that the standard guarantees
&b > &a. Positive integers are represented in twos-complement coding.
Unsigned integers occupy the the number of bits indicated by multiplying
sizeof(unsigned) by bits_per_char or whatever the appropriate #define is.
Now, if you're going to argue those guarantees don't count, Ok. I'd say some
do and some don't - I wouldn't argue that point very hard. But if they're
there, it's because enough people writing code in the language rely on them
being there that it was worth standardizing.
> The standard allows doing that even if it's undefined behavior simply
> because imposing restrictions on that would mean that compilers would
> have to generate significantly less efficient code even for programs
> which don't even attempt doing that. Many people don't mind.
Can I get you to come work for my company? :-)
--
Darren New, San Diego CA, USA (PST)
The question in today's corporate environment is not
so much "what color is your parachute?" as it is
"what color is your nose?"
Post a reply to this message
|
![](/i/fill.gif) |