POV-Ray : Newsgroups : povray.off-topic : This is the sort of brokenness... Server Time
6 Sep 2024 09:17:52 EDT (-0400)
  This is the sort of brokenness... (Message 31 to 40 of 164)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Warp
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 16:32:22
Message: <49c15a56@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> You still get subclasses. And of course there's always the hack of declaring 
> a subclass.

  A subclass can't access the private members of the base class.

> Or just using compiler-specific hackage to access the variables. 

  That has been made rather difficult in practice. If you are *intentionally*
trying to break your program, then that's your choice, of course. However,
in normal usage it's useful if the compiler checks that you don't make
mistakes.

> or the infamous "#define private public".

  Whether your program will link after that can depend on the compiler.
It's certainly not standard-conforming. And again, you are hacking on
purpose, trying to bypass the compiler checks, rather than using those
checks to catch your mistakes.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 16:36:10
Message: <49c15b3a@news.povray.org>
nemesis <nam### [at] gmailcom> wrote:
> Warp escreveu:
> > nemesis <nam### [at] gmailcom> wrote:
> >> I'm sorry, but that simply doesn't follow.
> > 
> >   Why not? Having the compiler check for breaking of agreements (eg. "don't
> > access these variables") is much better than oral agreements. The compiler
> > is much better at catching mistakes than you are.

> Now I (think I) understand the root of our disagreement.  I'm thinking 
> about functional programming here with only functions accessible per 
> interface, you're thinking about what variable can be accessed and 
> whatnot in a severely mutable setting.  It all becomes really hard when 
> you allow state to dominate.  So hard that even very experienced 
> programmers can face dificulty handling it all, thus having to invent 
> all sorts of levels of accessibility rather than just rely on lexical scope.

  Not all member functions have to be public either. It's extremely common
for a class to have private member functions which are part of its internal
implementation and not even intended to be part of the public interface.

  I would say that being able to define private member functions is equally
important as being able to define private member variables.

-- 
                                                          - Warp


Post a reply to this message

From: nemesis
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 16:58:57
Message: <49c16091$1@news.povray.org>
Warp escreveu:
> nemesis <nam### [at] gmailcom> wrote:
>> It's not because it's accessible that it is going to be used.
> 
>   Yeah, sure. If you are the *only* person making the entire program, then
> perhaps that might be the case.

Like I said, if the dumbass wants to use things not in the interface, 
it's his risk.

>   So in your opinion the concept of "interface" is a verbal agreement about
> what should and shouldn't be used from a module? *That* is what sounds like
> bureaucracy to me.

Not bureaucracy at all.  Just a list of names of functions a module 
provides.

>> For people who know it better, the lack of such measure does not mean 
>> irrestrict access to things, it simply means less stupid typing to make 
>> the compiler happy.  Modularity is conserved.
> 
>   In Utopia, maybe. In the read world, not so.

Indeed.  In real enterprise world we got people who don't enjoy nor know 
how to program, programming.  Or, should I say?, fill up a few forms and 
allow an IDE to generate the code.  It will spill shit all over, true.

>   And I don't consider having to write "private:" once to be significantly
> more typing.

Indeed, Delphi and C++ are yet more zippy at that, not so much for those 
poor Java souls... you also forgot the data type declarations.

> If I had to document what you should and should not access
> in the module, *that* would be significantly more typing.

This coming from a guy whose favorite language needs for one to provide 
the source and the header file.

 > And the kind of
 > text which most people will not read anyways.

It's usually the first thing one sees when opening a module.  (export 
foo bar boz frob etc)

>   Also, if I make a module for others to use, how can I guarantee that
> I can change the implementation later without breaking code others have
> written?

Don't change the interface.  Of course, if the implementation is changed 
in such a buggy way as to totally alter the behaviour, same interface 
doesn't mean jack.

>> It's all about scope.  If it's public, it should be used.  If it's not, 
>> you shouldn't.
> 
>   And what's wrong with the compiler telling you if you try to use it
> regardless? I really can't understand that.

Nothing wrong except quite a few more tiresome and bureaucratic measures 
before actually writing anything.

>   The compiler is not limiting anything that you aren't *already* limiting
> by your verbal agreement. The only thing the compiler is doing is checking
> that the agreement is not broken. Why that is a bad thing is beyond my
> comprehension.

I was not saying that is bad.  I was just reacting to this:  "Your 
definition of object-oriented programming may vary, but in my view
data hiding, ie. modularity, is an integral part of OO programming."

Modularity is still there regardless of dumb programmers ripping their 
contracts and no middleman to prevent them doing so.  But I'm thinking 
here on a typical Scheme module of old, before true modules, and where 
all you had was a list of functions and lexical scoping, not a C plain 
text file with lots of variables and variable-dependent functions lying 
all around.


Post a reply to this message

From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 17:01:07
Message: <49c16113@news.povray.org>
Warp wrote:
>> Like, in unsafe languages, where a stray pointer can change private 
>> variables without going thru the class methods? :-)
> 
>   No. The reasoning behind data hiding in modular thinking is completely
> independent of the language used. It has to do with program design.

OK. I guess you look it as "if you bypass the documentation and access 
members not documented, I have to support your brokenness forever." I look 
at it as "if you're coding from the implementation instead of the 
documentation, you get what you deserve" combined with "don't make me debug 
my code when the bug is in your code."

>   If you expose the internal structure of a module to the outside, then
> there's a big chance that outside will start making *assumptions* about
> this internal structure.

Sure. Most of these languages (a) document what's public and what isn't, and 
(b) have a language-wide naming convention for it.  That is, after all, what 
C++'s 'private' tag is - a naming convention.

>   If this happens, then you can't change the internal implementation of
> this module without breaking existing code. For example, if you wanted
> to change the color components to floats, or you would want to pack the
> color components into one single integral value, you will most probably
> break existing code (especially probable in the latter case, as the
> amount and names of the member variables will change drastically).
> 
>   If you can design the absolutely perfect module which will never change
> its contents and will suffice for years to come, then by all means make
> all members public. Us mortals will try smarter techniques.
> 
>> C# and Java both have reflection that let you get to private members from 
>> outside.
> 
>   Thus it's one reason why the design of these languages is badly broken.

I think it's more a trade-off than you make it out to be.

>> C++ not only lets you return pointers to private members
> 
>   Only if the class itself explicitly does so. You can't get to the private
> members *from the outside*.

That's why I said it wasn't much of a breakage in my view.

> (Well, at least not without some serious hacking.)

Running off the end of an array is "serious hacking"? I wouldn't think so.

>   I don't understand what you are saying. If a class in C++ does not expose
> a member array, then you can't get to that member array from the outside,

int * p = (int *) 0x123456;
*p = 27;

Find the bug in your code that's setting that member variable to 27.

How about
// Your code...
class xyz {
   public: int[10] x;
   private int y = 0;
}

// My code
  xyz pdq;
  pdq.x[10] = 27;


>   You might be able to control your *own* code from not misusing public
> variables (and you might never make mistakes), but it's more difficult to
> control someone else.

Sure. See above examples.

>   If you need to tell someone else "don't access member variables whose
> name start with an underscore", that's just plain stupid. You should be
> able to tell that by making the *compiler* enforce it.

I agree, except for the fact that you're using C++ as an example. :) C++ has 
it's own different lack-of-modularity problems. If the compiler actually 
*enforces* that the member variables you declare private can only be changed 
by your own methods, that's great.

"don't access member variables whose name starts with an underscore" is the 
kind of rule that's enforced all through a codebase or a programming 
language. The little extra warning the compiler is going to give you is 
generally not of much benefit if someone's going to violate that rule 
anyway, IME.  In other words, if they really need to violate the privacy of 
your class, they're going to do it in C++ almost as easily as they do it in 
something like Python or LISP.  The compiler doesn't enforce the 
encapsulation in C++ - it just gives warnings when you use a variable name 
that's private. There's no enforcement at runtime, and plenty of back doors 
at compile time. Contrast with, say, C#, where you don't even know what the 
private variables are named, and you couldn't access them if you did, 
because the runtime enforces that - there, the only backdoor is the 
reflection libraries that specifically are bypassing the privacy checking 
system. Using reflection (or explicitly assigning to _private members) isn't 
any more common or more prone to abuse than ((int*)0x12345)=27; is, 
particularly because the user has to explicitly know they're violating 
encapsulation when they write the code.

Granted, if you don't *document* in a universal kind of way what's public 
and what isn't, you're leaving yourself open to abuse.

But there are a lot of people who don't want to write a ton of boilerplate 
code for a function that could be automated, so they're willing to say "if 
you use introspection  to read and write my structure over the wire, be 
aware it may change in other versions."  It's better to say "this will break 
with future versions" than to say "I'm going to write 5000 lines of 
boilerplate code to allow clients to send my values over the internet or 
into databases."

There are also a whole bunch of assumptions in your classes that someone is 
going to rely on that you're not going to be able to prevent. SimCity 
assumed memory you called free() on would still be valid until the next 
malloc(), which is obviously a bad assumption yet still has to be supported 
by the infrastructure if you expect to run simcity on later versions of the 
OS. If you store your object outside of memory or interact with any other 
objects, you're also going to have random dependencies created - someone is 
going to have to change database schemas to store your objects in a 
database, or change buffer sizes if you switch from JSON serializiation to 
XML serialization without otherwise changing your interface. There will be 
people who assume your class only invokes their getter method once, if 
that's how you first code it, and if you change to invoking it twice, they 
may very well fail out (because they're pulling the next row from a database 
for each invocation, say). Or, in short, you can't protect against bad 
programmers, and anyone half-decent isn't going to be frobbing private 
variables to start with, IME.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: nemesis
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 17:01:24
Message: <49c16124@news.povray.org>
Rule #5:  Best documentation is the code. ;)


Post a reply to this message

From: nemesis
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 17:03:04
Message: <49c16188@news.povray.org>
Warp escreveu:
>   Not all member functions have to be public either. It's extremely common
> for a class to have private member functions which are part of its internal
> implementation and not even intended to be part of the public interface.

Exactly.  Lexical scoping takes care of that. For languages which allow 
conveniently-definable lambdas, that is.


Post a reply to this message

From: nemesis
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 17:05:18
Message: <49c1620e$1@news.povray.org>
Warp escreveu:
> And again, you are hacking on
> purpose, trying to bypass the compiler checks, rather than using those
> checks to catch your mistakes.

How this is any different from someone breaking a contract on purpose is 
beyond me.


Post a reply to this message

From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 17:06:49
Message: <49c16269$1@news.povray.org>
Warp wrote:
> 1) I write "private:" once in my class definition.
> 
> 2) I write extensive documentation about the subject and hope people will
>    read it and obey it. Many people won't.

You missed this one:
   3) You name your private variables with the naming convention used by
      every other package ever implemented in that language, including
      the ones that define the runtime, and which every programmer knows
      bypassing means future incompatibility.

>   And what's wrong with the compiler telling you if you try to use it
> regardless? I really can't understand that.

You already know you're using a private variable, if you're bypassing either 
global naming conventions or using reflection or something.

If the compiler actually *prevents* it, then you're locking yourself out of 
a whole bunch of metaprogramming techniques that templates aren't adequate 
to handle.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 17:10:18
Message: <49c1633a@news.povray.org>
Warp wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> Certainly if should-be-private members are exposed as public but don't 
>> document to the user which are private, that's a problem.
> 
>   I thought you were old enough to know some basic facts of life:
> 
> Rule #1: People *don't* read documentation.
> Rule #2: Read rule #1.
> Rule #3: Even if people read documentation, they do not have photographic
>          memory and they forget.
> Rule #4: Humans are imperfect and make mistakes.

Sure. "Don't read documentation" or "forget documentation" is as bad as 
"don't document it". But if it's a naming convention used throughout the 
language, people don't do it.

How many people name their own function to add a list of numbers as
   __builtin_addlist()
in C or C++?  Why not?  Because everyone who is even a little knowlegable 
knows that two underscore names are reserved for the compiler.

>   Why is it a bad thing to make the compiler check interface breaches is
> beyond my comprehension.

First, the whole "dynamic languages" bit at the start should indicate not 
everyone has a compiler for these languages. Secondly, it eliminates a whole 
raft of useful mechanisms.  Where's the C++ library to which I pass a class 
and it generates a SOAP interface parser for that class?

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 17:24:20
Message: <49c16684$1@news.povray.org>
Warp wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> You still get subclasses. And of course there's always the hack of declaring 
>> a subclass.
> 
>   A subclass can't access the private members of the base class.

Yeah, "protected" slipped my mind. It's still not hard to do if you're trying.

>> Or just using compiler-specific hackage to access the variables. 
> 
>   That has been made rather difficult in practice.

Err, has it? I can't say something like
   int * p = (int*) ((void*)(&yourInstance) + 32);
if I want access to whatever integer is 32 past the start of your class?

> If you are *intentionally*
> trying to break your program, then that's your choice, of course. However,
> in normal usage it's useful if the compiler checks that you don't make
> mistakes.

While I agree, I fail to see why using reflection as intended isn't "normal 
usage" and not "a mistake". It's not something you accidentally do. You know 
very well you're bypassing encapsulation. Not the least of which is that you 
need to give the name of the variable you want to access as a string.

>   Whether your program will link after that can depend on the compiler.
> It's certainly not standard-conforming. And again, you are hacking on
> purpose, trying to bypass the compiler checks, rather than using those
> checks to catch your mistakes.

Right. Since you said reflection violates encapsulation hard enough to make 
a program not "OO", I'm trying to figure out allowing type casts and 
assignment of arbitrary memory addresses to pointers doesn't.

Now, if the statement is "the compiler should be able to warn of external 
access to private variables, with the ability of the caller to easily 
indicate they know what they're doing," I'm 100% with you.

If the statement is "the compiler should error on external access to private 
variables, with no way to get around it," I'm 95% with you, with the caveat 
that "that's a pain in the ass way to write generic code that isn't type 
specific, because you have to write code generators instead of using the 
compiler you already have."

If the statement is "the compiler should error out on external access to 
private variables, but there should be a non-portable hacky and error-prone 
way to bypass it anyway, so you can't rely in your debugging efforts on what 
your code actually says," I'll just have to disagree with you there. :-)

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

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

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