[Grace-core] Class syntax and type parameters

Andrew P. Black black at cs.pdx.edu
Thu Nov 13 10:31:18 PST 2014


On 11 Nov 2014, at 16:20, Michael Homer <mwh at ecs.vuw.ac.nz> wrote:

Michael, if you move your sentences out of the passive voice and give them subjects, I think that you
will find that you are saying that you never found a use for inheritance between classes.  ("It’s intended that" => 
"I intended that”).  That’s fair enough.  But I did find such a use:  four classes (sequence, list, set, dictionary)
that all share the same methods (empty, with, withAll)).  

> You're creating extra fresh objects as a hack to get inheritance
> behaviour

Yes, that’s right.  I’m creating extra fresh objects because the language definition requires that I create extra fresh
objects.  In this situation they are stateless, so this is quite unnecessary, but that’s the way that we have defined
Grace.  Yes, I would like to see this simplified, but that’s not the scope of the current discussion.  Although the 
very fact that we have to have this discussion ought to indicate that the current design is unnecessarily complex. 

> I get the impression from this that you saw enabling this sort of
> approach as a deliberate part of the design,

Yes, I certainly see sharing of code between objects as a fundamental part of the design of inheritance in Grace.
And I think that we support sharing of pure code quite well.   Where it gets unreasonably complicated is in sharing 
initialization — which doesn’t come up in this example.

The complexity that started this email chain comes from having a special mechanism for parameterization 
by types, which has never been completely designed.  Marco asked, quite pertinently, whether we are sure that 
having such a mechanism in a language for novices is a good idea.  I think that  we should pay attention to this question!  

Tim, I did reply to James’s email.  To recap for the list:

> class collectionFactory.trait {
>      // requires withAll(elts : Collection<T>) -> Collection<T>
>      method with(*a) { self.withAll(a) }
>      method empty { self.with() }
>  }
> 
> Are you proposing to add the generic parameter to the trait? Why can it not just
> be on the methods? (with<T>(*a : T), empty<T>)

In this example, the type parameters can be on the methods.   I feel that this looses some expressivity,
namely, that with and empty both take the same type parameters.   Maybe I should just move them to the methods.   I added in the type 
parameters because the context-sensitive syntax checking that’s going on in the dupDecls branch was complaining (quite correctly) that there
were undeclared `T`s in the previous version of the code.

The “method or def” question came up when adding stuff to the symbol table.   When I process a class declaration, 
I have to decide whether to treat the class name as being a def or a method.    Some of the considerations are:

	- defs are confidential by default, whereas methods are public by default.   What about classes?
	- defs can’t be used to override inherited attributes, but methods can.  What about classes?
	- def’s can’t have type parameters, whereas methods can.   What about classes? 
 	- def’s cache the object that they answer, whereas methods create it afresh each time.  In the case of a class, 
  	   the object that they answer is a stateless object with a single method,  so this difference is semantically invisible.

In the spec, §8.8.2 says:  [Andrew] I don’t recall ever discussing the default encapsulation rules for classes. 
Should the class declaration be treated like a def, making the class confidential, or like a method, making it public? 

Can we at least decide on this?

	Andrew


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailhost.cecs.pdx.edu/pipermail/grace-core/attachments/20141113/2aae5695/attachment.html>


More information about the Grace-core mailing list