![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible wrote:
> Scientific applications are a vanishingly small market segment.
I'm not so sure about that.
>> That's not "mainstream", that's "popular". :-)
> There's a difference?
Yes.
>>> If you specifically want a binary tree, the simplest and most logical
>>> OO way would be to make leaves and branches different subclasses.
>>
>> Not especially. What about a branch with only one child node?
>
> Why would a branch have only one child?
Populate the tree one element at the time. At least half the time, you'll
have a node with only one child.
Perhaps the reason you don't see it a lot in Haskell is because the
definition of a node with only one leaf would be ugly. :-)
> I haven't seen an N-ary tree in an OO language. ;-) Only strictly
> *binary* trees.
Wow. You need to read more code. You've never seen a hashtable full of
hashtables, or a parse tree?
> Right. So any programming language that runs on a digital computer
> inherantly lacks encapsulation then?
Nope. If the language defines what happens when you try to violate
encapsulation, then you have encapsulation.
> That's a stupid definition. Encapsulation is about whether the language
> tries to limit your access to the internal implementation of an object,
> not about whether it's physically possible to circumvent the restriction
> by some suitably elaborate route.
Right. But in unsafe languages, it's not a matter of "suitably elaborate."
Let's ask this: what good is encapsulation? Why do people think
encapsulation is a good thing?
Answer: because it limits where you have to look to understand the behavior
of code. If your language has encapsulation, you can look at the class of
that object to determine what accesses and modifies its internal state. If
the language has encapsulation but also an escape to an unsafe language
(like JNI or P/Invoke or so), then you have to look at your class and all
unsafe code that might change the contents of your class.
Let's ask this: Why doesn't C++ have encapsulation?
Answer: Where in your code might lie a bug that is causing your class to
violate its invariants? If you have two variables in your instance, one of
which must always be two times the other, where do you have to look if that
is not the case? How much of your code base might cause that change?
>
>> What is this?
>>
>> (lambda (x) (x + 1))
>>
>> It's a lambda expression.
>>
>> y = (lambda (x) (x + 1))
>>
>> What is y? It's a closure.
>
> I still don't get it. (But then, I don't even know what language that
> is...)
Do you understand the difference between classes and instances?
>>> OK. So in what way does this mean that "functions are not first-class"?
>>
>> I didn't say it did. I said that everything in Javascript is an object.
>
> OK. So even a function is an object. Since objects are first-class, that
> means objects are first class.
Yes, and yes. And functions have the class "Function".
> YOU wrote this paragraph, not me. ;-)
OK. My bad. Altho that would certainly explain why I was confused. ;-)
> And this isn't the case for Haskell?
I don't know. Maybe it is, but you don't make it sound that way.
> As I said, the likes of Galois and Well Typed make their money primarily
> designing systems where correctness is vital. What kind of systems do
> you suppose those are?
I couldn't guess. Galios has an empty web site and Well Typed are consultants.
I'd honestly be quite surprised if either one builds systems in Haskell
where correctness is actually vital. As in, an error in the program means
people die.
> (It's also conspicuous that both Galois and Well Typed employ people who
> are also GHC developers... so maybe that's your answer!)
Yep.
--
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) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Let's ask this: Why doesn't C++ have encapsulation?
Clearly we have a different definition of "encapsulation".
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> Let's ask this: Why doesn't C++ have encapsulation?
>
> Clearly we have a different definition of "encapsulation".
I explained why encapsulation is important and why unsafe languages don't
have it. What's your definition of encapsulation, and why does it make a
difference to the programming productivity?
--
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) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Warp wrote:
> > Darren New <dne### [at] san rr com> wrote:
> >> Let's ask this: Why doesn't C++ have encapsulation?
> >
> > Clearly we have a different definition of "encapsulation".
> I explained why encapsulation is important and why unsafe languages don't
> have it. What's your definition of encapsulation, and why does it make a
> difference to the programming productivity?
It seems that in your quest to belittle "unsafe languages" you have taken
some obscure definition of a term somewhere, treat it as if it was the
unversally accepted definition, and point out how your beloved "unsafe
languages" don't conform to that obscure definition.
Encapsulation in object-oriented languages is not *my* definition:
http://en.wikipedia.org/wiki/Encapsulation_%28object-oriented_programming%29
Nowhere do I see anything related to what you wrote.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> It seems that in your quest to belittle "unsafe languages" you have taken
> some obscure definition of a term somewhere,
Not at all. I'm simply explaining why safety is important to encapsulation.
Do you think Python encapsulates data? If so, then C++ does too.
If you think Python insufficiently protects its data, then neither does any
unsafe-by-default language.
> Nowhere do I see anything related to what you wrote.
The whole "information hiding" bit, for one.
"""
Under this definition, encapsulation means that the internal representation
of an object is generally hidden from view outside of the object's definition.
"""
C++ fails this. Internal representation is in the header file. But that's
not what I'm talking about.
"""
Typically, only the object's own methods can directly inspect or manipulate
its fields.
"""
All unsafe languages fail this. (Lots of safe languages do too, with
appropriate declarations of their unsafeness.)
"""
Hiding the internals of the object protects its integrity by preventing
users from setting the internal data of the component into an invalid or
inconsistent state.
"""
Unsafe languages fail at this. Either that, or you have never ever
encountered a wild-pointer bug. The fact that you don't frequently violate
encapsulation doesn't mean that encapsulation is enforced, any more than the
fact that people don't usually screw around with the internals of Python
instances doesn't mean Python has good encapsulation in that sense.
In theory, yes, if you don't violate the language mechanisms, then C++
provides encapsulation. In practice, it doesn't, because when some value in
your object is randomly changed by a bug in some code running in other
thread, you're fairly well screwed in terms of figuring out the
encapsulation. That is, pretty much, the difference between safe languages
and unsafe languages: Safe languages *enforce* encapsulation. (And again,
most safe languages allow you to circumvent that by dropping into an unsafe
subset, but some don't.)
--
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) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> """
> Under this definition, encapsulation means that the internal representation
> of an object is generally hidden from view outside of the object's definition.
> """
> C++ fails this. Internal representation is in the header file. But that's
> not what I'm talking about.
"Data hiding" doesn't mean "hidden from the programmer", but "hidden from
the outside scope". In other words, code out of the scope of the class has
no direct access to the internals of the class (in other words, you get a
compiler error if you try to access).
You could as well argue that if you had an open source library in a language
with true data hiding (by your definition of the term), it stops being data
hiding because the programmer could just look at the source code of the
library and see the internal structure of the objects. Just because the
programmer can see the internal structure of the object doesn't stop it
from being data hiding.
The purpose of encapsulation and data hiding is not to obscure information
from the programmer, but to offer an abstraction tool for the program design.
(In that way "data hiding" is perhaps slightly a misnomer, and something like
"scope access restrictions" would be better.)
In other words, if you want to keep a good abstraction level in your
program, if something is marked as "private" then that something doesn't
interest you unless you are actually implementing the class which owns
that private member. Just because the class says explicitly "hey, I have
this private member" doesn't stop it from being encapsulation and data
hiding.
> """
> Typically, only the object's own methods can directly inspect or manipulate
> its fields.
> """
> All unsafe languages fail this. (Lots of safe languages do too, with
> appropriate declarations of their unsafeness.)
Now you are deliberately confusing a general non-restriction of memory
access with the concept of data hiding.
Again, data hiding is a tool offered by the language which you can use
to increase abstraction in your program. Just because the language doesn't
guarantee that modification of random memory locations using wild pointers
will always be caught doesn't make the tool nonexistent. The tool is still
there for you to use, and the compiler will enforce it as long as you write
your code as intended.
> """
> Hiding the internals of the object protects its integrity by preventing
> users from setting the internal data of the component into an invalid or
> inconsistent state.
> """
> Unsafe languages fail at this. Either that, or you have never ever
> encountered a wild-pointer bug.
A wild pointer bug is at a completely different conceptual level than
data hiding. Encapsulation exists as a tool for *programming*, not as a
tool for the runtime. If you use encapsulation as intended, and your
program is correct, then the compiler will enforce the encapsulation.
> In theory, yes, if you don't violate the language mechanisms, then C++
> provides encapsulation. In practice, it doesn't, because when some value in
> your object is randomly changed by a bug in some code running in other
> thread, you're fairly well screwed in terms of figuring out the
> encapsulation.
I think that your problem is that you somehow write like having bugs
in your program is some kind of valid programming technique. "Encapsulation
should be enforced even if there are bugs in your program" sounds quite
silly. It kind of implies that "your program should still run ok even if
there are bugs in it".
Assume that you have a bug in your program in that you forgot to write
"private" in conjunction with a member declaration, making it public.
There's a bug in your program, which made the member accessible from the
outside. By your definition this programming language doesn't enforce
encapsulation because if there are bugs in your program it may allow
private members to be accessible from the outside.
That's just silly. You cannot define the concept of encapsulation in
terms of buggy programming.
> That is, pretty much, the difference between safe languages
> and unsafe languages: Safe languages *enforce* encapsulation.
No, they don't. If you make a programming error and inadvertedly make
a member public, the compiler will do squat about that.
You are deliberately confusing a programming technique such as
encapsulation with a runtime technique such as memory protection.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> "Data hiding" doesn't mean "hidden from the programmer", but "hidden from
> the outside scope".
Fair enough. If that's how you want to look at it.
The way I see it is that encapsulation is a mechanism to reduce the area you
have to look to understand or use or debug a particular part of a program.
It makes things modular. The less modular changes are, the less encapsulated
the changes are.
If you can't see or access the private variables at all, that's extremely
encapsulated. If you can see and access them only through reflection or
explicitly-declared unsafe operations, that's less encapsulated. If you need
to see them because changes in private parts mean you have to deal with it
in your own code (say, by recompiling or changing the size of structure
declarations), that's also less encapsulated. When a bug in one part of the
program can cause arbitrary changes elsewhere, that's really minor
encapsulation.
I find "the compiler tells you if you explicitly write code that tries to
access stuff you can see but is flagged private" as the weakest form of
encapsulation out there, in terms of "information hiding". Only something
like Python that doesn't even try is weaker than that.
> In other words, code out of the scope of the class has
> no direct access to the internals of the class
And you understand why I'm disputing that this is the case, right?
*Correct* code has no direct access to the internals of the class *by name.*
Incorrect code has direct access to the internals of the class, and correct
code has direct access as long as it doesn't do so by name. (For example,
write(outfile, &myInstance, sizeof myInstance);
> You could as well argue that if you had an open source library in a language
> with true data hiding (by your definition of the term), it stops being data
> hiding because the programmer could just look at the source code of the
> library and see the internal structure of the objects. Just because the
> programmer can see the internal structure of the object doesn't stop it
> from being data hiding.
No. I'm not talking about just the programmer.
> The purpose of encapsulation and data hiding is not to obscure information
> from the programmer, but to offer an abstraction tool for the program design.
That's one of many purposes. I think the primary purpose is not to say "this
is public and that is private", which could be done as easily by a naming
convention or comments, but to also allow for debugging, understanding,
production pipelines, etc.
This abstraction is the only encapsulation that C++ provides, so naturally
that's what you think the purpose of encapsulation is. But there's a whole
bunch of reasons for encapsulation. Plus, these additional forms of
encapsulation have all kinds of other benefits, which is why (for example)
you don't see applets written in C++.
> (In that way "data hiding" is perhaps slightly a misnomer, and something like
> "scope access restrictions" would be better.)
Now who is changing definitions? :-)
> In other words, if you want to keep a good abstraction level in your
> program, if something is marked as "private" then that something doesn't
> interest you unless you are actually implementing the class which owns
> that private member.
And in Python, if a variable name starts with _ then that variable doesn't
interest you. Does that mean Python has encapsulation like C++ does?
In languages where the private variables aren't exposed at all, this
question doesn't even come up. So C++ (and Ada, and the other languages that
increase efficiency by exposing the private declarations to client code)
isn't even very good at this. You wouldn't even *need* a "private"
declaration in the header file but for that. It wouldn't be a case of "the
compiler tells me that's private" as much as "the compiler tells me that's
not a member of the class."
>> All unsafe languages fail this. (Lots of safe languages do too, with
>> appropriate declarations of their unsafeness.)
>
> Now you are deliberately confusing a general non-restriction of memory
> access with the concept of data hiding.
No. You're confusing data hiding with encapsulation. You've changed the
subject from "encapsulation" to "data hiding", because data hiding is the
*only* kind of encapsulation C++ supports.
If you asked me if C++ supports data hiding, I would have said "Yes, poorly,
because you can see what's there and have to deal with it, but the compiler
enforces the private keyword."
I told you why encapsulation is important, listing several reasons. Data
hiding is just one of them.
> Again, data hiding is a tool offered by the language which you can use
> to increase abstraction in your program. Just because the language doesn't
> guarantee that modification of random memory locations using wild pointers
> will always be caught doesn't make the tool nonexistent. The tool is still
> there for you to use, and the compiler will enforce it as long as you write
> your code as intended.
That's correct. But that's not all that encapsulation encompasses. "Data
hiding" is not the only thing that encapsulation provides.
>
>> """
>> Hiding the internals of the object protects its integrity by preventing
>> users from setting the internal data of the component into an invalid or
>> inconsistent state.
>> """
>
>> Unsafe languages fail at this. Either that, or you have never ever
>> encountered a wild-pointer bug.
>
> A wild pointer bug is at a completely different conceptual level than
> data hiding.
Yep. Not the point tho. It's at a different conceptual level, which is
exactly *why* it is so hard to debug. You can't look at the assignments to
the variable and figure out which one might have set the denominator of your
Fraction class to zero.
Look, I'm just going thru the definition *you* pointed me at and showing
that unsafe languages don't meet the definition.
You don't need to hide the internal variables to prevent someone from
setting them to an invalid state. For example, Eiffel has clauses in the
source code that describe the valid states of internal variables, so you
could in theory check at each assignment that nobody outside the class is
breaking the internal consistency.
The only way in which hiding data prevents the consistency from being
corrupted is if it's actually inaccessible when it is hidden. Unsafe
languages fail at that. You can clobber and make inconsistent data that is
hidden at the "conceptual level" of the language.
> Encapsulation exists as a tool for *programming*, not as a
> tool for the runtime.
I disagree. Considering what the compiler does without considering what the
runtime does says little about your language. You're the one that says C++
is superior to Java because of the runtime.
Runtime encapsulation is what made Java popular in the first place. Indeed,
runtime encapsulation was pretty much the entire point of Java's development.
> If you use encapsulation as intended, and your
> program is correct, then the compiler will enforce the encapsulation.
I already granted that "if your program is correct" then C++ has a minimal
level of encapsulation. That's not really saying much, tho. "If your program
is correct" in Python, you don't screw with publicly-accessible members that
aren't documented. That doesn't mean Python has as good encapsulation as
C++ does.
> I think that your problem is that you somehow write like having bugs
> in your program is some kind of valid programming technique.
No. I write like someone who codes against libraries built by people who
aren't as good a programmer as I am. We're long past the point in computers
where people run "their program" in an environment where every bug is
guaranteed to be their own.
Heck, even *with* the runtime encapsulation that Javascript enjoys, people
*still* run separate tabs in separate processes.
> "Encapsulation
> should be enforced even if there are bugs in your program" sounds quite
> silly.
Tell that to people running Java applets in their web browser. I mean, isn't
that basically the difference between Java applets and ActiveX?
> It kind of implies that "your program should still run ok even if
> there are bugs in it".
You know something? There's an awful lot of software that falls into this
category. Know why? Because programmers aren't perfect.
> Assume that you have a bug in your program in that you forgot to write
> "private" in conjunction with a member declaration, making it public.
> There's a bug in your program, which made the member accessible from the
> outside. By your definition this programming language doesn't enforce
> encapsulation because if there are bugs in your program it may allow
> private members to be accessible from the outside.
Not at all. The difference is that when I go to my class where the problem
manifests as incorrect data in instance variables, and I look through the
code that references those ought-to-be-private variables and see that none
of them set it wrong, and then I look at the declaration and see it's
public, I can change that to private and see who is accessing it that
shouldn't.
On the other hand, when you have a wild pointer bug overwrite my instance
variable, the place I have to look in the code to find that is *everywhere.*
Including code I don't have source for.
You're either trolling me, or you're a really crappy and/or inexperienced
programmer if you don't understand the difference between the scale of
looking for a bug in those two places. The whole *point* of encapsulation is
not to serve as documentation as to what's public and what's private, but to
limit the amount of code you have to look at to understand the behavior of a
given variable.
> That's just silly. You cannot define the concept of encapsulation in
> terms of buggy programming.
Yes! You can! That's exactly the point. You're encapsulating who can change
what values, so it's easy to find.
That's like saying "You cannot define the concept of structured programming
based on not executing gotos to arbitrary locations, because if you're
careful with your gotos, it's the same code as structured programming."
Sure, that's exactly what it is, because you're *guaranteeing* that the
structure is there. You don't have to check every goto to make sure it's
only a goto from the end of "then" to the end of "else" or some such.
>> That is, pretty much, the difference between safe languages
>> and unsafe languages: Safe languages *enforce* encapsulation.
>
> No, they don't. If you make a programming error and inadvertedly make
> a member public, the compiler will do squat about that.
True, but now you're asking the compiler to detect errors in *correct*
programs, which is orders of magnitude harder than asking the compiler to
detect errors in incorrect programs. There are very few compilers that will
detect that the program doesn't match the spec, altho LOTOS and Eiffel both try.
> You are deliberately confusing a programming technique such as
> encapsulation with a runtime technique such as memory protection.
Not really. Indeed, when taken to extremes, encapsulation enforces safe
language features. By using a "safe pointer" in C++, you've encapsulated the
operations on the pointer and ensure you don't do something like access it
after it's disposed. By using a "container" instead of just an array, you've
encapsulated access to the container's elements and can enforce that you
don't go out of bounds or throw an exception if you change it during
iteration or some such.
--
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) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> When a bug in one part of the
> program can cause arbitrary changes elsewhere, that's really minor
> encapsulation.
You are still confusing a runtime memory protection mechanism with the
programming technique of data encapsulation.
"A bug in the program breaks encapsulation promises" doesn't imply there's
no encapsulation. It only implies that there's a bug in your program which
makes it misbehave.
You might argue that encapsulation without runtime memory protection of
the modules is worthless (or at least less useful), but that's a different
thing from claiming that there's *no* encapsulation. Encapsulation is a
programming technique, not a runtime mechanism. The memory protection
encompasses a lot more than just protecting module members from being
trashed.
> > In other words, code out of the scope of the class has
> > no direct access to the internals of the class
> And you understand why I'm disputing that this is the case, right?
> *Correct* code has no direct access to the internals of the class *by name.*
> Incorrect code has direct access to the internals of the class, and correct
> code has direct access as long as it doesn't do so by name. (For example,
> write(outfile, &myInstance, sizeof myInstance);
You are still confusing runtime memory protection with the programming
technique of encapsulation.
> > (In that way "data hiding" is perhaps slightly a misnomer, and something like
> > "scope access restrictions" would be better.)
> Now who is changing definitions? :-)
Suggesting a more descriptive term is not changing the definition.
Data hiding has always been about access rights.
> > In other words, if you want to keep a good abstraction level in your
> > program, if something is marked as "private" then that something doesn't
> > interest you unless you are actually implementing the class which owns
> > that private member.
> And in Python, if a variable name starts with _ then that variable doesn't
> interest you. Does that mean Python has encapsulation like C++ does?
Does the compiler give you an error if you try to access the private
variable from the outside?
> In languages where the private variables aren't exposed at all, this
> question doesn't even come up.
Where the private members are specified is inconsequential.
> > Now you are deliberately confusing a general non-restriction of memory
> > access with the concept of data hiding.
> No. You're confusing data hiding with encapsulation. You've changed the
> subject from "encapsulation" to "data hiding", because data hiding is the
> *only* kind of encapsulation C++ supports.
They are used as synonyms, and I'm not the only one to do so.
> If you asked me if C++ supports data hiding, I would have said "Yes, poorly,
> because you can see what's there and have to deal with it, but the compiler
> enforces the private keyword."
As I said, you could as well argue that if you look into the source code
of a library and see the internal structure of the object, it breaks data
hiding and thus the programming language has "poor support" for it.
Just because the programmer can see what the object is composed of doesn't
mean there's no data hiding. Data hiding is about access rights.
> I told you why encapsulation is important, listing several reasons. Data
> hiding is just one of them.
Your definition of encapsulation is mixed with a runtime mechanism of
memory protection. I don't see that requirement anywhere.
> You're the one that says C++ is superior to Java because of the runtime.
I don't even understand what you mean by that, or where I have said such
a thing. My complaints about Java are mainly based on its language features
(such as the inability to abstract a basic type away). These are basically
all compile-time features.
> Runtime encapsulation is what made Java popular in the first place. Indeed,
> runtime encapsulation was pretty much the entire point of Java's development.
No, what made Java popular was garbage collection (and lacking some
features which some people saw as "bad", such as multiple inheritance).
Also the idea of "write once, run everywhere".
> > "Encapsulation
> > should be enforced even if there are bugs in your program" sounds quite
> > silly.
> Tell that to people running Java applets in their web browser. I mean, isn't
> that basically the difference between Java applets and ActiveX?
Now you are confusing it with sandboxing, another memory protection
mechanism.
> > It kind of implies that "your program should still run ok even if
> > there are bugs in it".
> You know something? There's an awful lot of software that falls into this
> category. Know why? Because programmers aren't perfect.
And this is related to the definition of encapsulation how?
> > Assume that you have a bug in your program in that you forgot to write
> > "private" in conjunction with a member declaration, making it public.
> > There's a bug in your program, which made the member accessible from the
> > outside. By your definition this programming language doesn't enforce
> > encapsulation because if there are bugs in your program it may allow
> > private members to be accessible from the outside.
> Not at all. The difference is that when I go to my class where the problem
> manifests as incorrect data in instance variables, and I look through the
> code that references those ought-to-be-private variables and see that none
> of them set it wrong, and then I look at the declaration and see it's
> public, I can change that to private and see who is accessing it that
> shouldn't.
> On the other hand, when you have a wild pointer bug overwrite my instance
> variable, the place I have to look in the code to find that is *everywhere.*
> Including code I don't have source for.
Some bugs are easier to find than others. This has what to do with the
definition of "encapsulation"?
If there's a bug in the operating system which randomly trashes the
memory of a program, does that mean the programming language which was
used to create that program has no encapsulation?
What if the runtime which executes the program has a bug which trashes
its memory. Does that mean the programming language has no encapsulation?
If there's a faulty RAM chip in your computer which causes part of the
program's memory to be trashed, does that mean there's no encapsulation in
the programming language?
You are confusing runtime memory protection with the programming technique
of encapsulation. They are different things.
> You're either trolling me, or you're a really crappy and/or inexperienced
> programmer if you don't understand the difference between the scale of
> looking for a bug in those two places.
Some bugs are easier to find than others. This has what to do with the
definition of "encapsulation"?
> The whole *point* of encapsulation is
> not to serve as documentation as to what's public and what's private, but to
> limit the amount of code you have to look at to understand the behavior of a
> given variable.
And you arbitrarily set the limit of what still constitutes as acceptable
"encapsulation" and what doesn't somewhere between the program's own runtime
and the OS.
> > That's just silly. You cannot define the concept of encapsulation in
> > terms of buggy programming.
> Yes! You can! That's exactly the point. You're encapsulating who can change
> what values, so it's easy to find.
Well, in that case no programming language supports encapsulation, then.
If there's a bug in the runtime which trashes your program's memory, those
private members can be changed.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> When a bug in one part of the
>> program can cause arbitrary changes elsewhere, that's really minor
>> encapsulation.
>
> You are still confusing a runtime memory protection mechanism with the
> programming technique of data encapsulation.
We will have to agree to disagree.
> "A bug in the program breaks encapsulation promises" doesn't imply there's
> no encapsulation.
It implies you have very little encapsulation.
Seriously, what is the value of encapsulation if a bug can disrupt it? I've
never found encapsulation in unsafe languages any more useful than a naming
convention is in a safe language.
Note that's a serious question. I'm not mocking or trying to prove a point.
I'm simply trying to figure out why you think "private:" is noticeably
better than a naming convention or documentation.
I'm also seriously asking why you think encapsulation is at all valuable.
What benefit does it give you in practice, that would be difficult to obtain
just by having decent documentation?
> You might argue that encapsulation without runtime memory protection of
> the modules is worthless (or at least less useful), but that's a different
> thing from claiming that there's *no* encapsulation.
There's very *little* encapsulation. There's attempted encapsulation. :-)
> Encapsulation is a programming technique, not a runtime mechanism.
Right. But a programming technique that is designed to make debugging and
understanding the interactions of parts of a program easier yet that doesn't
actually do so is a poor implementation, IMO.
What do you think is the benefit of encapsulation to the programming process?
> You are still confusing runtime memory protection with the programming
> technique of encapsulation.
I'm just going by the definition you pointed me to. If you want a different
definition, let's see it. Maybe I'll agree with it. :-)
>>> (In that way "data hiding" is perhaps slightly a misnomer, and something like
>>> "scope access restrictions" would be better.)
>
>> Now who is changing definitions? :-)
>
> Suggesting a more descriptive term is not changing the definition.
> Data hiding has always been about access rights.
Yes, but we're not talking about data hiding. We're talking about
encapsulation. I'll grant that C++ has a weak form of data hiding, yes.
>> And in Python, if a variable name starts with _ then that variable doesn't
>> interest you. Does that mean Python has encapsulation like C++ does?
>
> Does the compiler give you an error if you try to access the private
> variable from the outside?
Probably not. Do you think that would make a difference? That when you're
typing in the name of the member variable, you don't notice it starts with
an underscore?
>> In languages where the private variables aren't exposed at all, this
>> question doesn't even come up.
>
> Where the private members are specified is inconsequential.
Well, I'll have to disagree again there. The fact that you can see them and
access them
>> No. You're confusing data hiding with encapsulation. You've changed the
>> subject from "encapsulation" to "data hiding", because data hiding is the
>> *only* kind of encapsulation C++ supports.
>
> They are used as synonyms, and I'm not the only one to do so.
Well, I'm making a distinction. You can have one without the other. People
make lots of mistakes by not knowing as wide a range of possibilities as
they should, thinking that (for example) static typing means you have to
specify the types of variables, or that object-oriented means you have
instances of classes, or etc.
>> If you asked me if C++ supports data hiding, I would have said "Yes, poorly,
>> because you can see what's there and have to deal with it, but the compiler
>> enforces the private keyword."
>
> As I said, you could as well argue that if you look into the source code
> of a library and see the internal structure of the object, it breaks data
> hiding and thus the programming language has "poor support" for it.
Not really, because there are legal and valid ways of getting to those
private variables in C++, guaranteed to work by the language. If the private
variables really were private, you'd have no reason to specify how they're
laid out in memory, since the only code that could get to them is the class
itself.
> Just because the programmer can see what the object is composed of doesn't
> mean there's no data hiding. Data hiding is about access rights.
OK. I disagree, but OK.
>> I told you why encapsulation is important, listing several reasons. Data
>> hiding is just one of them.
>
> Your definition of encapsulation is mixed with a runtime mechanism of
> memory protection. I don't see that requirement anywhere.
There doesn't have to be any memory protection involved. Java doesn't have
memory protection, but applets are encapsulated. Erlang doesn't have memory
protection, but it has encapsulation.
>> You're the one that says C++ is superior to Java because of the runtime.
>
> I don't even understand what you mean by that, or where I have said such
> a thing. My complaints about Java are mainly based on its language features
> (such as the inability to abstract a basic type away).
You complain that everything in Java has to be allocated on the heap, for
example. Which is purely a runtime mechanism that has little to do with the
language. (As shown by the newer compilers that don't allocate all objects
on the heap, yet compile standard Java, for example.)
>> Runtime encapsulation is what made Java popular in the first place. Indeed,
>> runtime encapsulation was pretty much the entire point of Java's development.
>
> No, what made Java popular was garbage collection (and lacking some
> features which some people saw as "bad", such as multiple inheritance).
> Also the idea of "write once, run everywhere".
And nobody would have heard of it if it weren't for applets. Trust me on
this one - I was there.
Anyway, Java stuff snipped, since it's irrelevant to the conversation.
>> > It kind of implies that "your program should still run ok even if
>>> there are bugs in it".
>
>> You know something? There's an awful lot of software that falls into this
>> category. Know why? Because programmers aren't perfect.
>
> And this is related to the definition of encapsulation how?
Because if your definition only applies to bug-free software, claiming that
your program supports it isn't a very useful property.
> Some bugs are easier to find than others. This has what to do with the
> definition of "encapsulation"?
Because encapsulation is there to help you find bugs! It's there to help
you understand the program and to ensure that each piece works how it's
supposed to in isolation. To ensure that testing one piece and seeing that
it works means it works when combined with other pieces.
I.e., that a class is correct as implemented.
> If there's a bug in the operating system which randomly trashes the
> memory of a program, does that mean the programming language which was
> used to create that program has no encapsulation?
No, because that's outside the scope of the programming language's definition.
C++ on the other hand guarantees that you can access stuff by indexing
outside the defined boundaries of objects. Hence the assurance that things
are laid out in the order you declare them, the ability to use write() to
store data from classes into files, etc. ("Write()" still lets you write out
a class, doesn't it?)
> What if the runtime which executes the program has a bug which trashes
> its memory. Does that mean the programming language has no encapsulation?
No, but it means the encapsulation has failed. It also means that that
particular interpreter does not correctly implement the encapsulation that
the language defined. You could say that if the JVM randomly scribbles over
private values, then that JVM did not correctly implement Java.
But C++ defines mechanisms for violating encapsulation, both accidentally
and on purpose.
> If there's a faulty RAM chip in your computer which causes part of the
> program's memory to be trashed, does that mean there's no encapsulation in
> the programming language?
No, it means your computer did not correctly implement the programming language.
> You are confusing runtime memory protection with the programming technique
> of encapsulation. They are different things.
I explained how they're not.
>> You're either trolling me, or you're a really crappy and/or inexperienced
>> programmer if you don't understand the difference between the scale of
>> looking for a bug in those two places.
>
> Some bugs are easier to find than others. This has what to do with the
> definition of "encapsulation"?
Because encapsulation is there to make finding bugs easier.
>> The whole *point* of encapsulation is
>> not to serve as documentation as to what's public and what's private, but to
>> limit the amount of code you have to look at to understand the behavior of a
>> given variable.
>
> And you arbitrarily set the limit of what still constitutes as acceptable
> "encapsulation" and what doesn't somewhere between the program's own runtime
> and the OS.
Because the language's runtime is part of the definition of the language.
The OS usually isn't. Sometimes it is, in which case yes, if the OS is
specific to the language you're using, then a failure in the OS is a
violation of encapsulation.
>> Yes! You can! That's exactly the point. You're encapsulating who can change
>> what values, so it's easy to find.
>
> Well, in that case no programming language supports encapsulation, then.
> If there's a bug in the runtime which trashes your program's memory, those
> private members can be changed.
It's not a binary choice. Of course if your hardware fails and changes
random values in your program, then there's a problem you need to track
down. But if you can prove that no method of your class should be changing
one of Java's private variables set in the constructor but it changes
anyway, then you know the code that's broken isn't Java code. You know it's
the OS, or JVM, or hardware, or something.
In contrast, C++ has well-defined mechanisms for bypassing the encapsulation
that are used as a normal part of programming in that language.
--
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) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Seriously, what is the value of encapsulation if a bug can disrupt it? I've
> never found encapsulation in unsafe languages any more useful than a naming
> convention is in a safe language.
I have found it extremely useful. For example, my FunctionParser library
(which has got some popularity) is, basically, one class with a relatively
brief public interface.
During its history the library has gone through two major rewrites (the
second one almost completely from scratch, reusing only some portions of
the old version), yet without breaking the public interface and hence the
programs using it. This means that programs which use the library can safely
upgrade to a newer version of the library and still work just fine.
As you might imagine, the almost complete rewrites have also entailed an
almost complete redesign of the private parts of the class, which have
usually ended up being completely unlike the older versions. The public
interface has stayed almost completely intact (except for some additions
which don't break backwards compatibility), which means that existing
programs don't break.
*That* is the beauty of encapsulation.
Of course I'm sure you have some obscure name from some obscure source
for that as well, just for the sake of disagreement.
> I'm also seriously asking why you think encapsulation is at all valuable.
> What benefit does it give you in practice, that would be difficult to obtain
> just by having decent documentation?
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? Given that it's quite easy for compilers to do that, then why not?
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.
It also makes it clearer in inheritance what the derived class can and
shouldn't access: The base class' private part is private, but it might
offer a 'protected' part for derived classes to use. The compiler then
explicitly checks that this abstraction level is obeyed. Easier and better
than just having some comments saying "this can be be used in derived
classes but should not be accessed from the outside".
So yes, it's much better if the compiler tells the user he is accessing
what he shouldn't.
> > You are still confusing runtime memory protection with the programming
> > technique of encapsulation.
> I'm just going by the definition you pointed me to. If you want a different
> definition, let's see it. Maybe I'll agree with it. :-)
But where do you draw the line between what is and isn't encapsulation?
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?
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?
> 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.
The memory layout of objects is completely implementation-defined and thus
while you can read the individual bytes of the memory location where the
object is, you cannot safely make any assumptions about their meaning. And
trying to *modify* the memory occupied by the object is outright undefined
behavior.
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.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |