[Grace-core] Visibility of variables and constants in Objects

James Noble kjx at ecs.vuw.ac.nz
Wed Jul 3 02:27:06 PDT 2013


> access through self would be easier to implement if self.x always meant an invocation of a method.

I'll let Michael talk about the implementation...

> (Am I correct that this is the source of the concern?).

No. Perhaps the simplest formulation is from Andrew's example:

  method p {1} 

should be replaceable by

  var p = 1
  def p = 1
  var p = 1 is readable
  var p = 1 is public
  var p = 1 is readable, public

(assuming the program has no definition of a p:= method)

without changing the semantics of the program - even in the presence of inheritance

> It is also the case that lexical scoping gives static rather than dynamic dispatch, but calls to self in the body are dynamically dispatched, and -- because of visibility constraints, there is no reason to explain the difference to students. -- it's an implementation detail. (I'm sure someone will correct me if I am wrong here. )

explicit requests to self a dynamically dispatched.
implicit requests may be either statically or lexically "dispatched" - that's the issue.

the current rule says something like:
1. IF there's a definition in self, and it's a method, or var/def with implicit method - > dynamic
    (may resolve to subclass defn)
2. IF there's a definition in self that's a var/def without implicit methods -> lexical/static binding
    (will not resolve to subclass defn if there is one)

3a. IF there's a definition in outer, or outer.outer...  out to the dialect, - candidate lexically bound
3b. IF there;s a definition in super, or super.super... out to whatever the top is called - candidate dynamically bound
3c. IF only one candidate from 3a & 3b, do that.  ELSE error

> If that is correct then I don't see that has much impact on the programmer, though it makes the compiler writer's life more complicated. 

the impact - the different semantics - currently arise only when looking at the code of a superclass where a superclass field is overridden by a subclass method.

> While I have a slight preference for having private as well as confidential and public features,



> it


> does make the language simpler for the student (fewer features) if we only have confidential and public, and that has some advantages. In our intro, we start with private and public, and only introduce protected (in Java) half way through the course. 
> 
> I do strongly agree with Andrew that our original principal of making it easier to do the correct thing should make the default for instance variables to be private (or if it doesn't exist confidential). I originally wanted the same defaults for methods so that students would have to think about what should be accessible rather than the reverse. I conceded to the practical argument that most methods are public and that it adds a lot of noise to the code to require it (though I would be happy to go back). I do believe with Andrew that encapsulation/info hiding is a key aspect of OO languages so would be happiest providing more support by default rather than the reverse. 
> 
> Kim
> 
> Sent from my iPad
> 
> On Jul 3, 2013, at 8:25 AM, "Andrew P. Black" <black at cs.pdx.edu> wrote:
> 
>> Folks,
>> 
>> I've been thinking more about the discussion that we (James, Andrew, Michael and Kim) had yesterday (at ECOOP) about visibility of defs and vars in objects.
>> 
>> I'm sympathetic to the theoretical principle  that annotations should only restrict otherwise legal programs, and not make otherwise incorrect programs work.  However, I also believe in encapsulation as one of the core values of OOP.   Making defs and vars in objects public, just so that we can use annotations to restrict access to them, seems to fly in the face of encapsulation.  We have said many times that programs that "do the right thing" should be shorter than programs that don't.  Most of the time, access to variables and constants defined in an object should be restricted to the methods in that object.   So this should be the default.
>> 
>> I don't have a problem with the default for methods being public.  That's the reason to have a method: so that clients can request it.
>> 
>> I also like to think of the "publiclyReadable" annotation (or whatever we call it) as generating a method.  I know that there is an alternative view in which variable access itself can be dynamically bound, an in Self and in Java.  But I think that the "generated method" view is easier to explain to novices and easier to understand.  The rules for method lookup are then simple and uniform.   Maybe the objection to annotations liberalizing programs could be overcome by replacing this particular annotation by a new keyword, such as field or feature.  Maybe "is method" is better than "is publiclyReadable"
>> 
>> I don't yet understand why making variable and constant access lexical makes the name resolution rules any more complicated than they would be without such lexical access.  We already have lexical access to parameters and temporaries, both in the current scope and in lexically enclosing scopes.  We therefore already need rules that disambiguate between requests of methods and access to defs.  Why is the access to x in the example below any more complicated than the access to p?
>> 
>>     object {
>>         method new(p) {
>> 	    object {
>>                 def x = 56
>>                 method doit(q) {
>>                     (p + x) ^ q
>>                 }
>>             }
>>         }
>>     } 
>> 
>> In the following example, is the use of p in doit a method request or a use of the parameter of new?   We have to have a rule about this, and we have to teach it, and it's embarrassing that the language is so complicated that I'm not sure what it is!   But whether x is always dynamically or always lexically bound won't fix this problem.  The only "fix" would be to get rid of lexical binding altogether, including in blocks that capture their environment, and including parameters.  None of us thinks that this would be a good idea!
>> 
>>     object {
>>         method new(p) {
>> 	    object {
>>                 def x = 56
>> 		method p {1}
>>                 method doit(q) {
>>                     (p + x) ^ q
>>                 }
>>             }
>>         }
>>     } 
>> 
>> I'm very interested in talking about this more and finding out why the changes that you proposed would help.
>> 
>> 	Andrew
>> 
>> 			    
>> 		
>> _______________________________________________
>> Grace-core mailing list
>> Grace-core at cecs.pdx.edu
>> https://mailhost.cecs.pdx.edu/mailman/listinfo/grace-core
> _______________________________________________
> Grace-core mailing list
> Grace-core at cecs.pdx.edu
> https://mailhost.cecs.pdx.edu/mailman/listinfo/grace-core
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailhost.cecs.pdx.edu/pipermail/grace-core/attachments/20130703/2ef44b24/attachment.html>


More information about the Grace-core mailing list