POV-Ray : Newsgroups : povray.off-topic : Why is Haskell interesting? Server Time
4 Sep 2024 23:20:41 EDT (-0400)
  Why is Haskell interesting? (Message 61 to 70 of 87)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Warp
Subject: Re: Why is Haskell interesting?
Date: 1 Mar 2010 15:02:44
Message: <4b8c1d64@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> Warp wrote:
> > Darren New <dne### [at] sanrrcom> 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

From: Darren New
Subject: Re: Why is Haskell interesting?
Date: 1 Mar 2010 16:04:09
Message: <4b8c2bc9$1@news.povray.org>
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

From: Warp
Subject: Re: Why is Haskell interesting?
Date: 1 Mar 2010 16:42:15
Message: <4b8c34b7@news.povray.org>
Darren New <dne### [at] sanrrcom> 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

From: Darren New
Subject: Re: Why is Haskell interesting?
Date: 1 Mar 2010 17:22:18
Message: <4b8c3e1a@news.povray.org>
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

From: Warp
Subject: Re: Why is Haskell interesting?
Date: 1 Mar 2010 18:16:49
Message: <4b8c4adf@news.povray.org>
Darren New <dne### [at] sanrrcom> 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

From: Darren New
Subject: Re: Why is Haskell interesting?
Date: 1 Mar 2010 19:20:38
Message: <4b8c59d6$1@news.povray.org>
Warp wrote:
> Darren New <dne### [at] sanrrcom> 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

From: Warp
Subject: Re: Why is Haskell interesting?
Date: 1 Mar 2010 19:58:26
Message: <4b8c62b2@news.povray.org>
Darren New <dne### [at] sanrrcom> 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

From: Darren New
Subject: Re: Why is Haskell interesting?
Date: 1 Mar 2010 20:44:56
Message: <4b8c6d98$1@news.povray.org>
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

From: Invisible
Subject: Re: Why is Haskell interesting?
Date: 2 Mar 2010 04:25:45
Message: <4b8cd999$1@news.povray.org>
>> Scientific applications are a vanishingly small market segment.
> 
> I'm not so sure about that.

How many people use computers to do scientific calculations?

How many people use computers to run their office suite?

Yeah, exactly.

>>> That's not "mainstream", that's "popular". :-)
>> There's a difference?
> 
> Yes.

Care to elaborate on what it is?

>> 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.

How do you figure that?

Tree with 1 element: L
Tree with 2 elements: L + L
Tree with 3 elements: L + (L + L)
Tree with 4 elements: (L + L) + (L + L)

Every node has either zero or two children.

> 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. :-)

No, it would be as trivial as the usual binary tree.

>> 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?

I've never read the implementation of a hash table, for that matter.

Now a *parse tree* probably has a much more complicated structure than a 
simple binary tree. I can well imagine it containing nodes with all 
sorts of numbers of children. (And there might well be some complicated 
inheritance relationships between the node types.)

> 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?

In just about any programming language imaginable, it would be possible 
to look at the raw assembly code generated to figure out where some data 
is physically stored in memory, and then link in some raw assembly to 
directly access that data. So by this argument, because it's technically 
possible to circumvent the language restrictions in just about any 
programming language, no programming language exists which supports 
encapsulation.

Which is, of course, nonesense. Real programs don't do this kind of 
thing. If your program doesn't attempt to circumvent encapsulation, then 
you get the benefits of encapsulation.

>>> 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?

Yes. (But I'm not sure how this is related to functions...)

>> YOU wrote this paragraph, not me. ;-)
> 
> OK. My bad.  Altho that would certainly explain why I was confused. ;-)

Heh. Talking to yourself is the first sign of madness. ;-)

>> And this isn't the case for Haskell?
> 
> I don't know. Maybe it is, but you don't make it sound that way.

I can't even remember what this statement refers to now...

>> 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.

No, I think it's more "failure would cost us craploads of money, very 
fast". I believe that's the kind of area they work in. (They also seem 
to do quite a bit of government work.)

>> (It's also conspicuous that both Galois and Well Typed employ people 
>> who are also GHC developers... so maybe that's your answer!)
> 
> Yep.

Of course, if you're the language implementers, you can implement 
whatever you want. ;-) (Within reason, of course...)

I wonder if any of the other Haskell compilers will be production-ready 
any time soon?


Post a reply to this message

From: Darren New
Subject: Re: Why is Haskell interesting?
Date: 2 Mar 2010 11:33:16
Message: <4b8d3dcc$1@news.povray.org>
Invisible wrote:
>>> Scientific applications are a vanishingly small market segment.
>>
>> I'm not so sure about that.
> 
> How many people use computers to do scientific calculations?
> How many people use computers to run their office suite?
> Yeah, exactly.

Sure. I wouldn't say "vanishingly small", given the number of offices that 
actually do science for a living.

> Care to elaborate on what it is?

Not especially. Let's just mention "COBOL".

> Every node has either zero or two children.

Fair dinkum. I was thinking of a different algorithm.

> I've never read the implementation of a hash table, for that matter.

You should. I expect things like skip lists and skip graphs and DHTs are the 
sorts of things you'd get into.

> In just about any programming language imaginable, it would be possible 
> to look at the raw assembly code generated to figure out where some data 
> is physically stored in memory, and then link in some raw assembly to 
> directly access that data. 

So, because you can link assembly code to your Haskell, that means Haskell 
isn't functional? Because assembly code isn't functional?

> Which is, of course, nonesense. Real programs don't do this kind of 
> thing. If your program doesn't attempt to circumvent encapsulation, then 
> you get the benefits of encapsulation.

Uh, no. That's my point. You might get some of the benefits of encapsulation 
(like correct code being easier to understand), but if neither the compiler 
nor the runtime enforce encapsulation and you have no way of detecting 
errors that violate encapsulation, then your language is doing a poor job of 
encapsulation, at least for many of the benefits of encapsulation.

>>>> 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?
> 
> Yes. (But I'm not sure how this is related to functions...)

"Lambda" is the class. "Closure" is the instance.

Lambda is an expression. A closure is the value of the expression.

What is this:
    \ x . x + y

It's a lambda expression. It's not a value, because you don't know what "y" 
is. It means different things depending on where it is in the program and 
when you evaluate it. Every time you evaluate it, you'll get something 
different back, depending on "y", yes?

That thing you get back, that encapsulates the value of "y"? That's a closure.

> Heh. Talking to yourself is the first sign of madness. ;-)

Oh, you can't help that. We're all mad here.

-- 
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

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.