POV-Ray : Newsgroups : povray.off-topic : Why is Haskell interesting? : Re: Why is Haskell interesting? Server Time
4 Sep 2024 19:21:29 EDT (-0400)
  Re: Why is Haskell interesting?  
From: Darren New
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

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