www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Eiffel field/method access control

reply z gg.com writes:
In C++/Java world, there're 3(4) keywords for access control:
private/protected/pubic, and C++ also has friend.

Suppose a Person has a bankAccount (only Bank should know), and a nickName (only
Classmate should know).  The best we can do with Java/C++ is:

class Bank {...}
class Classmate {...}

class Person {
private string bankAccount;
private string nickName;

friend class Bank;
friend class Classmate;
}

However, why should Classmate also can access my bankAccount? and why should
Bank know my nickName?

Eiffel's answer: we don't need all these keywords at all.  But for each
field/method, we just define its access list.  Now we can do much better:

class Wife {...}
class Neighbour {...}

class Person {
{Bank, Wife} string bankAccount;
{Classmate, Wife, Neighbour} string nickName;
{Person, Doctor}  Stomach;  // :-)
}

And any sub-class of a member in the access list also have access to that
attribute.

In this way the traditional private/protected/pubic can be expressed as:

private   -> {/*empty*/}
protected -> {this /**/}
public    -> {Object /* the top object everyone inherits */}

Thoughts? comments?
Jul 11 2005
next sibling parent reply AJG <AJG_member pathlink.com> writes:
Doesn't this get tedious and unmaintainable after a while?

Seems a lot more verbose too. I suppose everything has its place, but is there a
problem with public/protected/private?

One last thing: IMHO "friend" access is an abomination. I don't know why on
earth it's the default in D for classes within the same file.

I think using "friends" is the result of either sloppiness (i.e. a quick
prototype) or poor architecture. My general rule of thumb is: If you do

# someClass.m_somePrivateMember

Then something funky is going on.

--AJG.

In article <dav7nb$2hm5$1 digitaldaemon.com>, z gg.com says...
In C++/Java world, there're 3(4) keywords for access control:
private/protected/pubic, and C++ also has friend.

Suppose a Person has a bankAccount (only Bank should know), and a nickName (only
Classmate should know).  The best we can do with Java/C++ is:

class Bank {...}
class Classmate {...}

class Person {
private string bankAccount;
private string nickName;

friend class Bank;
friend class Classmate;
}

However, why should Classmate also can access my bankAccount? and why should
Bank know my nickName?

Eiffel's answer: we don't need all these keywords at all.  But for each
field/method, we just define its access list.  Now we can do much better:

class Wife {...}
class Neighbour {...}

class Person {
{Bank, Wife} string bankAccount;
{Classmate, Wife, Neighbour} string nickName;
{Person, Doctor}  Stomach;  // :-)
}

And any sub-class of a member in the access list also have access to that
attribute.

In this way the traditional private/protected/pubic can be expressed as:

private   -> {/*empty*/}
protected -> {this /**/}
public    -> {Object /* the top object everyone inherits */}

Thoughts? comments?

Jul 11 2005
next sibling parent z gg.com writes:
In article <davb6b$2kft$1 digitaldaemon.com>, AJG says...
Doesn't this get tedious and unmaintainable after a while?

No, it actually gives you more safety. And in practice, if you suspect something wrong with a field/method, you can quickly look at its access list, and know who can modify it. In contrast, for a 'public' field/method, you have too grep all over the place to find out the potential clients who modify it.
Seems a lot more verbose too. I suppose everything has its place,
but is there a problem with public/protected/private?

Do you see a problem in the example I give in my original post? How would you solve it just by public/protected/private?
class Bank {...}
class Classmate {...}

class Person {
private string bankAccount;
private string nickName;

friend class Bank;
friend class Classmate;
}

However, why should Classmate also can access my bankAccount? and
why should Bank know my nickName?


One last thing: IMHO "friend" access is an abomination. I don't know
why on earth it's the default in D for classes within the same file.

Inherited from Java's rule, I guess.
I think using "friends" is the result of either sloppiness (i.e. a quick
prototype) or poor architecture. My general rule of thumb is: If you do

# someClass.m_somePrivateMember

Then something funky is going on.

Well, I think 'friend' is the wrong way to solve the problem. But those problems do exist. And I believe Eiffel's approach is more elegant and general.
Jul 11 2005
prev sibling parent David Medlock <noone nowhere.com> writes:
AJG wrote:

 Doesn't this get tedious and unmaintainable after a while?
 
 Seems a lot more verbose too. I suppose everything has its place, but is there
a
 problem with public/protected/private?
 
 One last thing: IMHO "friend" access is an abomination. I don't know why on
 earth it's the default in D for classes within the same file.

Because there is no need to protect a class within a file from another class in the same file. The same person is most likely writing both classes. So you wish to tie his hands to make some imaginary OOP protections? The type system should be there to serve me, not the other way around. Personally I think its a great feature that I can write a function in a file with 2 classes and access them both as I wish. This also avoids the 'who calls who' issue in designing an API. I cannot stand programming languages which do not assume *you know what you are doing*. Programming should be as pragmatic as possible. In the end we are trying to get things accomplished, not create some arcane semantical rules to live by. -DavidM
Jul 12 2005
prev sibling next sibling parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
 In this way the traditional private/protected/pubic can be expressed as:

 private   -> {/*empty*/}
 protected -> {this /**/}
 public    -> {Object /* the top object everyone inherits */}

 Thoughts? comments?

One obvious question is what about top-level functions? They are not methods of any class so would they have to be listed exiplicitly in the permission list?
Jul 12 2005
prev sibling parent reply Dejan Lekic <leka entropy.tmok.com> writes:
Modula-3 has something better and IMHO more elegant: Partial revelation.
More about it: http://research.compaq.com/SRC/modula-3/html/partial-rev/ 

Regards

-- 
...........
Dejan Lekic
  http://dejan.lekic.org
  
Jul 12 2005
parent Charles Hixson <charleshixsn earthlink.net> writes:
Dejan Lekic wrote:
 Modula-3 has something better and IMHO more elegant: Partial revelation.
 More about it: http://research.compaq.com/SRC/modula-3/html/partial-rev/ 
 
 Regards
 

Modula-3 appears to me to be as dead as Sather. Even deader than Modula-2. (And Eiffel appears headed the same way. For that matter, so does Ada, with their decision not to mandate garbage collection in the recent 200x revision of their specs.) This is tragic, as Modula-3 had some very nice features, and both Eiffel and Ada had magnificent potentials. But Eiffel and Ada each made choices that sidelined them even more than their lack of PR did. I never heard of Modula-3 or Sather before they were moribund. Still, I draw a few lessons: 1) Don't be unduly restrictive with your language, either in it's specification or in it's availability. (Yeah D!) 2) Design the language so that it's easy to use without compromising efficiency. (Yeah D!) 3) Allow public criticism. (Yeah D!) Note also that the good points of D (the one's mentioned above) are shared by several other languages, like Python and Ruby. So you need to find you niche and expand from there in ways that don't limit your use in the primary niche. My main criticism about D is that I wish it was easier to be more dynamic. But D's pretty good, and dynamism hampers efficiency, so there's a trade off. Once there was a Forth dialect called Neon (it died during the transition from Mac to MSWind) that handled this with a special syntax that indicated late binding. The specific problem I have is with reading in a data structure when you don't know ahead of time what kind of structure it is. So you read, say, the first int, and that tells you the type...which means that you need some registry of the possible types... sigh. In a language like Python or Ruby this presents no problem, they call it "Duck typing", and the value returned by the initialization routine is recognized by the messages that it can respond to. I can't see how that facility could be added to D without doing violence to it's basic nature (and efficiency), but I do miss it. void just doesn't substitute.
Jul 12 2005