[Grace-core] Class syntax and type parameters

Andrew P. Black black at cs.pdx.edu
Tue Nov 11 15:08:25 PST 2014


Michael,

I believe that it would really help both you and the project as a whole if you took a few moments to explain what you are saying, both in your emails and in meetings, and why you come to these conclusions.   You are obviously very smart and very quick, but these traits help us if you don’t trouble to explain your reasoning.

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

> On Wed, Nov 12, 2014 at 10:04 AM, Andrew P. Black <black at cs.pdx.edu> wrote:
>> More on classes with type parameters.
>> 
>> Here is the use case that prompted the question that I raised in the teleconference yesterday.
>> 
>> factory method list<T> {
>>    inherits collectionFactory.trait<T>
>> 
>>    method withAll(a:Collection<T>) -> List<T> {
>>        object {
>>            inherits indexable.trait<T>
>>            var inner := _prelude.PrimitiveArray.new(a.size * 2 + 1)
>>            var size is public := 0
>>            for (a) do {x->
>>                inner.at(size)put(x)
>>                size := size + 1
>>            }
>>>> 
>> Notice that it’s necessary for the type parameter to go on the constructor object `list` rather than on the method `withAll()`: if the parameter is on `withAll()`, then it’s nor accessible on line 2 where it is needed to parameterize the inherited trait.
>> 
>> So we have inconsistent naming:
>> 
>>        list<T>.withAll
>> 
>> but
>> 
>>        collectionFactory.trait<T>
>> 
>> because the latter is declared with the class syntax, and therefor can only — by virtue of Michael Homers pronouncement — be parameterized as above.
> What you're doing is fundamentally unsupported by the inheritance
> system, 

Could you please explain what you mean when you write “What you're doing”.  I’m doing several things at once — which one are you referring to?    Do you mean using inheritance to share (pure) methods between objects?   I agree that Grace’s inheritance system needs work, but that is surely something that it can do.  Do you mean adding type annotations to the collections prelude?   I don’t see that as “fundamentally unsupported” either — there may be deficiencies in the type system, but fundamentally we do want it to be able to cope with typed collections.   I’m at a loss to understand your point — although it’s clear that you feel very passionately about it.
 
> and so you can't expect it to flow.
> When you hack something
> together consistency is a bonus if you can get it.

What are you suggesting that I’ve hacked together?

>> This motivated by original question: does
>> 
>>        class a.b { object constructor body }
>> 
>> mean (1)
>> 
>>        def a is public = object {
>>                method b {
>>                        object { object constructor body }
>>                }
>>        }
>> 
>> or (2)
>> 
>>        method a  {
>>                object {
>>                        method b {
>>                                object { object constructor body }
>>                        }
>>                }
>>        }
>> 
>> I had always assumed (1), but now (2) looks more reasonable.

> #2 has all the disadvantages of both dotted and non-dotted classes
> while managing to avoid picking up any of their advantages. (The same
> applies to your original list at the top, in fact.)

#2 wasn’t supposed to have any of the advantages of dotted classes or non-dotted factory methods — it was supposed to be a suggested translation for the dotted class notation (what Kim would call an “encoding”, I think).
> 
> There is a fundamental choice to be made about whether you want
> classes to be first-class entities before or after generic
> instantiation. You can't have both.

Well, we could have both, if we made functions first-class.   But I agree that we haven’t done that yet, and for good reason.  
Most programmers will never see the difference between (1) and (2).   With the first translation, `a` denotes an object.  With the second translation, `a` is a method request that answers an object.  Since that object itself captures no state,  the difference is pretty much philosophical, I think.   If `a` has type parameters, then those are implicitly given the value `Unknown` before the method request is made — `a` is still legal.

> I don't know what people want. If
> you're programming without types then "after" is quite confusing.

Don’t we have exactly the same confusion with parameterized type definitions like List<T>?    List is strictly a (type) function, but I can use it as a type, where it means List<Unknown>  

> "Neither" is non-dotted classes.

Are you saying that, if we don’t have the dotted class notation, then there is no question to be answered?  That seems obvious; if we just have factory methods then there is only one method that be parameterized by type, so it’s clear which method is parameterized by type.   I have a feeling that you are intending to say something less obvious, but I’m at a loss to know what.

	Andrew


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


More information about the Grace-core mailing list