[Grace-core] collections interface for new classes

James Noble kjx at ecs.vuw.ac.nz
Thu Dec 10 07:03:38 PST 2015


> But my point was that the typical user won’t write collections.list[a, b, c] or collections.list.with[a, b, c].  They will write list[a, b, c] or list.with[a, b, c].
> That may influence how we choose to name stuff.

yes, you’re right, and I think it will - which (in conjunction with literal collections, but not varags) gets to 

>> This does simplify things though:
>> list [] - empty list
>> list [a,b,c] - literal list
>> list(foo) - build list from a collection foo 

(note that kernan currently requires "list ([a,b,c])” rather than “list [a,b,c]” - Michael, what’s the issue there?) 

> Obviously, I’m invested in the current set of interfaces.

list.empty // empty list
list.with(a,b,c)  // list of elements, needs varargs
list.withAll( foo ) // build list from a collection foo 
 
>  I’ve redesigned them three times.  They are not perfect, I’m sure, but they have suffered through two ten week teaching sequences, and many mutations due to feedback from students.  


yes, I know - and it’s probably irritating to have me going over them again.
but if we really are dropping varargs, the current interfaces no longer work. 
This is partly why I was not that keen on dropping varargs — at least until I’m sure we can do at least as as good an interface.
I’m slightly more keen on dropping varargs now, because it seems that “list []” version works quite well

(note that kernan currently requires "list ([a,b,c])” rather than “list [a,b,c]” - Michael, what’s the issue there?) 


>> collection constructors now feel like wrappers over the builtin sequences
>> 
>> the other question is: do [] collections have a minimal or a maximal interface:
>> do we have to write “seq [1,2,3]” or will just "[1,2,3]" do?
> 
> So, I suggest that […] support the `Iterable` interface.  This is smaller than Sequence, in that it does not support indexing or tests for containment.  It doesn’t even support `size`!  This is perhaps going too far, since the size of a […] literal will always be known.   Maybe we need a slightly larger type FiniteIterable that has a size method. 

Kernan’s varargs list don’t support size.
that gets irritating pretty quick - e.g. even to copy into an array you have to iterate through to size it first.
ideally we should do something about size.  I think java8 has a good model there, but don’t know the details

> We could also use the `Collection` interface:
> 
> type Collection<T> = Iterable<T> & type {
>    asList -> List<T>
>    asSequence -> Sequence<T>
>    asSet -> Set<T>
> } 

I’m keen fewer interfaces, rather than more. 
>From the usability point of view, it will be confusing if there are some things that []s can do, but many things they can’t do.


One way to put the design question is:  if people are writing code with literal, read-only sequences 
do we want them to just write e.g.

>  for [ “hearts”, “clubs”, “spades”, “diamonds” ] do { suit ->  … } 

or must they write 

> for (seq [ “hearts”, “clubs”, “spades”, “diamonds” ]) do { suit ->  … } 


or even 

> for (seq ([ “hearts”, “clubs”, “spades”, “diamonds” ])) do { suit ->  … } 

as against the varags-based, Scala-compatible

> for (seq ( “hearts”, “clubs”, “spades”, “diamonds” )) do { suit ->  … } 



hmm. now I’ve almost convinced myself back again that we want varargs and [] accessors 
and don’t want [ ] literals, because Scala!  (no, because I think list( a, b, c,) is not about
syntatically as good as [a, b, c] …   which brings us back to “all” 


>>> I don't understand what your `all` wrapper would do.
> 
> I’m asking: what is “that” ?


so, conceptually the varargs implementation of “sequence” with “all” would somewhere be something: 

> method sequence (*elems) {
>    var result := emptySequence
>    for (elems) do { e -> 
>        match (e) 
>             case { _ : All -> result := result.addAll(e) }
>             case { _ -> result := result.addLast(e) } 
>    }
> }

using “all" you’d write:

list                    // list.empty
list(a, b, c)         // list.with(a, b, c)
list( all(foo) )      // list.withAll( foo ) 



ideally someone should look at Java8, Scala, python, Smalltalk, Dart, Swift, Self...
do a proper domain analysis of collections, and come up with a design.
Unfortunately that would take months, make a good Masters thesis, or/and ECOOP paper...

>>> Finally, the place for this discussion is in the gracelang/languages issue tracker.

there are more people on grace-core than look there, even if few of them respond any more…

J


More information about the Grace-core mailing list