Thread overview
Eiffel field/method access control
Jul 12, 2005
z
Jul 12, 2005
AJG
Jul 12, 2005
z
Jul 12, 2005
David Medlock
Jul 12, 2005
Ben Hinkle
Jul 12, 2005
Dejan Lekic
Jul 13, 2005
Charles Hixson
July 12, 2005
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?


July 12, 2005
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?
>
>


July 12, 2005
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.


July 12, 2005
> 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?


July 12, 2005
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

July 12, 2005
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

July 13, 2005
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
> 
I note the date on that article: 1999.

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.