[Grace-core] more comments on collections

Kim Bruce kim at cs.pomona.edu
Thu Jul 17 14:40:22 PDT 2014


> 
>> A (perhaps picky) conceptual issue with your library design.  Operations like remove on sets returns "self", which makes it convenient to chain together operations.  However, other operations like "-" returns a new list.  
> 
> Perhaps you mean - on sets?

Yest, that was a typo
> 
>> I find it a bit confusing that both have essentially the same type (and otherwise look very similar).  This requires very good comments (and the user to read them!) to understand when the operation is a mutates the current data structure and when it results in a new one.  I'm not sure what the right answer is (don't worry about chaining operations?), but it seems like it would be confusing, especially to new programmers.
> 
> Well, perhaps.  Certainly the types do not tell the client what the operations do; for that you need a specification.   My thought was that sets should have the mathematical set operations (union, intersection, and difference), and that these should answer new sets, whereas operation like remove and add mutate the receiver.   This seems clear to me from the names — but, as you say, not necessarily clear to novices.  

I understand now.  Good documentation will help.  Certainly if I include them in the text I now know the explanation.
>  
> 
>> Here are the types of List<T> and Set<T> as I've extracted them from your code.  One question:  Why both add and addAll in List, 
> 
> Because add() takes a variable arity argument list.   But, as we have discussed previously, if you want to call add() and you have a collection of things to add, we have no syntax to “explode” that collection into an argument list.    So we need addAll, and the convention that whenever one defines a variable arity method, one should always do so in terms of another method that takes a collection. I violated that rule with remove, which I should supplement with removeAll.

Makes sense
> 
>> where add in Set seems to be like addAll in List rather than add.  
> 
> add in list should be a variable arity method too.  Good catch.   
> 
>> Also set has a copy operation, while list doesn't.  Why?  
> 
> Another oversight on my part.  The interfaces came from mgcollections, which is where some of the strange names come from (e.g, push)
> 
>> Finally Range's == seems to require a Collection<T> for the argument, while == for List and Set both accept any Object.  Consistency would be useful.
> 
> I agree.  I wrote range first.   Do we want equality to work between the receiver and any object, or just between the receiver and types that might be equal?

I don't have strong feelings.  There are issues with subtyping if the parameter type varies, so it might be easier if the default version compares the receiver and anything, and then programmers can define more specialized types if they like.  However, the main thing is to be consistent.
>> 
> 
>> type List<T> = {  
>>     at(n: Number) -> T
>>    [](n: Number) -> T
> 
> keep both of these?

I'd like to keep both.  I prefer to use the "at", while many of you prefer the other.  The text uses "at", but explains that the other exists for consistency with other languages.
> 
>>    at(n: Number)put(x: T) -> List<T>
>>    []:=(n: Number,x: T) -> List<T> 
> 
> keep both of these?
Yes for the same reasons
> 
>>    add(x: T) -> List<T>
>>    push(x: T) -> List<T>
> 
> delete this?
I don't see any need to keep push unless there is short-term need to keep the compiler going.
> 
>>    addLast(x: T) -> List<T>    // compatibility
>>    removeLast -> T 
>>    addFirst(x: T) -> List<T> 
>>    removeFirst -> T 
>>    removeAt(n: Number) -> T
>>    pop -> T
> 
> delete this?
Yup
> 
>>    indices -> List<Number>   // range type?
> 
> It does return a range, which is a Sequence type — like List, but without the mutators.

My mistake, it is clearly range in the code.
> 
>>    first -> T 
>>    second -> T
>>    third -> T
>>    fourth -> T 
>>    last -> T 
>>    ++(o: List<T>) -> List<T>
>>    asString -> String
>>    addAll(l) -> List<T>
>>    extend(l: List<T>) -> Done
> 
> delete this; extend(l) is a synonym for { addAll(); done }, introduced for compatibility with mgcollections. 
I also don't like having second, third, fourth.  It's arbitrary how far you go.
> 
>>    contains(element) -> Boolean
>>    do(block1: Block1<T,Done>) -> Done
>>    ==(other: Object) -> Boolean
>>    iterator -> Iterator<T>
> 
> you forgot the methods in enumerable.trait
> 
>     do(body:Block1<T,Done>)separatedBy(separator:Block0<Done>) -> Done
>     fold(blk:Block1<T,X>)startingWith(initial:T) -> X
>     map(blk:Block1<T,X>) -> Iterator<X>
>     filter(condition:Block1<T,Boolean>) -> Iterator<T>
>> }

Yes, another oversight on my part.
>> 
>> type Set<T> = {
>>     size -> Number
>>     add(*elements:T) -> Set<T>
>>     remove(*elements: T) -> Set<T>
>>     remove(*elements: T)ifAbsent(block: Block0<Done>) -> Set<T>
>>     contains(x: T) -> Boolean
>>     includes(booleanBlock: Block1<T,Boolean>) -> Boolean
>>     find(booleanBlock: Block1<T,Boolean>)ifNone(notFoundBlock: Block0<T>) -> T
>>     asString -> String
>>     -(o: T) -> Set<T>
>>     extend(l: Collection<T>) -> Set<T>
>>     do(block1<T,Done>) -> Done
>>     iterator -> Iterator<T>
>>     ==(other: Object) -> Boolean
>>     copy -> Set<T>
>> }
>> 
>> I'm having trouble typing dictionary because of the tricky defs of unused and removed, which don't have the right types.  I may have to recode to make it typable.  Any suggestions/concerns?
> 
> I personally wouldn’t bother — typing the i interfaces is very useful, but typing the internals will do nothing but slow these methods down.  However, if you really want to, then the PrimitiveArray inside a dictionary object should be a PrimitiveArray<T|Marker>, where Marker is a type that describes the Markers unused and removed, each of which should be a singleton type.
> 
> I’ll make some corrections based on what you wrote above.  But now we have three versions — in Collections, in StnadardPrelude, and in setsNLists.   That’s 2 too many for me to track ...

I agree, let's pick one (with type annotations -- for documentation if nothing else) and keep it as the master.
> 
> 	Andrew
> 

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


More information about the Grace-core mailing list