New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

constructors to create Java arrays with streams of elements #6797

Closed
gavinking opened this Issue Dec 3, 2016 · 29 comments

Comments

Projects
None yet
2 participants
@gavinking
Contributor

gavinking commented Dec 3, 2016

Currently we can create Java arrays with a given size (just like in Java). We can even specify a single element value which will fill the array. But we have to resort to ceylon.interop.java if we want to instantiate a Java array from a stream of elements. I think that ObjectArray and friends should each have a constructor named with() that accepts a stream. For example:

value longArray = LongArray.with { 1, 2, 3, 4 };

One for you, @tombentley ;-)

@gavinking gavinking added the t-feature label Dec 3, 2016

@gavinking gavinking added this to the 1.3.2 milestone Dec 3, 2016

@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 3, 2016

Oh, and I guess there could also be a static method that unwraps an Array:

Array<Integer> intArray = .... ;
value longArray = LongArray.from(intArray);

But note that ObjectArray.from() would only accept Array<T?>, never arrays of non-null element type, as in ceylon.interop.java today.

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 7, 2016

Done.

@tombentley tombentley closed this Dec 7, 2016

@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 7, 2016

Excellent!! Thanks Tom. WDYT of from() @tombentley? Should I open a second issue for it?

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 7, 2016

Oh, yeah, I forgot about that extra part...

@tombentley tombentley reopened this Dec 7, 2016

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 7, 2016

Isn't it a bit confusing if from is a constructor, given that it's not constructing anything. A static method would be more appropriate, no?

@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 7, 2016

@tombentley I wrote static method, not constructor.

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 7, 2016

Good, so you agree then :-)

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 8, 2016

Do we have IntArray.from(Array<Integer> array) (which will need to copy the long[] owned by the Array into an int[])? Or should I skip this method for IntArray, ShortArray and FloatArray?

@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 8, 2016

It should be IntArray.from(Array<java.lang.Integer> array) I think.

And I guess it's LongArray.from(Array<Integer>|Array<java.lang.Long> array).

Does tat look right?

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 8, 2016

Eugh

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 8, 2016

What about characters? Do I have CharArray.from(Array<java.lang.Character>) and IntArray.from(Array<java.lang.Integer|ceylon.language.Character> array)?

@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 8, 2016

Yes, I suppose so.

@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 8, 2016

@tombentley while trying to use this stuff, I'm getting errors like this:

[ceylon-compile] /Users/gavin/ceylon-ide-intellij/plugin-ceylon-code/source/org/intellij/plugins/ceylon/ide/ceylonCode/refactoring/IdeaChangeParameterRefactoring.ceylon:294: error: Ceylon backend error: method invoked with incorrect number of arguments; expected 1, found 0
[ceylon-compile]         setColumnInfos(ObjectArray<AnyColumnInfo>.with {typeColumn, nameColumn});
[ceylon-compile]                       ^

gavinking added a commit that referenced this issue Dec 8, 2016

object arrays can contain nulls
+ use type abbreviations #6797
@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 8, 2016

OK, @tombentley I can reproduce this bug now.

void setIt(ObjectArray<Integer> arr) {}
setIt(ObjectArray.with{1, 2, 3});

Results in:

source/mytest/List.ceylon:57: error: Ceylon backend error: incompatible types: Object[] cannot be converted to Integer[]
    setIt(ObjectArray.with{1, 2, 3});
                          ^
source/mytest/List.ceylon:57: error: Ceylon backend error: method invoked with incorrect number of arguments; expected 1, found 0
    setIt(ObjectArray.with{1, 2, 3});
         ^
@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 8, 2016

Ok, ta

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 8, 2016

Is there an ObjectArray.from()? I assume so, but then I have to deal with

    ObjectArray<Integer> integerArray = ObjectArray<Integer>.from(Array{1, 2, 3});
    ObjectArray<JLong> jlongArray = ObjectArray<JLong>.from(Array{JLong(1), JLong(2), JLong(3)});

Both Arrays internally are a long[], but I'll need to wrap the elements and allocate a new array to represent this as an ObjectArray. But there's no choice, right, because I can express the type

Array<T> given T isn't any of the the types we map to primitive arrays
@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 8, 2016

@tombentley see my comment above:

But note that ObjectArray.from() would only accept Array<T?>, never arrays of non-null element type, as in ceylon.interop.java today.

@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 8, 2016

And since Array is an invariant type, that does sorta act as a lower bound o T.

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 8, 2016

And then, of course there's the ambiguous:

ObjectArray<Object>.from(Array{JLong(1), JLong(2), JLong(3)});

Obviously I can allocate an Object[], but do I fill it with Long or c.l.Integer instances?

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 8, 2016

But note that ObjectArray.from() would only accept Array<T?>, never arrays of non-null element type, as in ceylon.interop.java today.

Ah, I think I finally understand this cryptic comment -- it's so we never have to deal with Arrays wrapping primitive arrays. Riiiight!

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 8, 2016

Why is there a constaint given T satisfies Object on ObjectArray.T? I don't think it really breaks anything, but I don't understand why it's needed.

@gavinking

This comment has been minimized.

Contributor

gavinking commented Dec 8, 2016

@tombentley it just better reflects the reified type of Java object arrays.

@tombentley

This comment has been minimized.

Contributor

tombentley commented Dec 9, 2016

@gavinking, for

ObjectArray<Object>(Array<Object?>) objRef = ObjectArray<Object>.from;

the QME from has no target:

+  [QualifiedMemberExpression] (171:53-171:76) : unknown : function ObjectArray<T>.from<T>(Array<T?> array) => ObjectArray<T>
|  + from [Identifier] (171:73-171:76)
|  +  [InferredTypeArguments]
|  +  [BaseTypeExpression] (171:53-171:71) : ObjectArray<Object>(Integer, Object?=) : ObjectArray<Object> : class ObjectArray<T>(Integer size, T? element)
|  |  + ObjectArray [Identifier] (171:53-171:63)
|  |  + <> [TypeArgumentList] (171:64-171:71) : <Object>
|  |  |  +  [BaseType] (171:65-171:70) : Object : class Object()
|  |  |  |  + Object [Identifier] (171:65-171:70)
|  + . [MemberOp] (171:72-171:72)

How can I figure out the typed parameters in this case?

@tombentley

This comment has been minimized.

Contributor

tombentley commented Jan 4, 2017

@gavinking can you answer my question

@tombentley

This comment has been minimized.

Contributor

tombentley commented Jan 19, 2017

@gavinking, I can't progress this until I understand this

@gavinking

This comment has been minimized.

Contributor

gavinking commented Jan 19, 2017

@tombentley:

function ObjectArray<T>.from<T>

That doesn't look right. Why does from() have a type parameter? ObjectArray is already parameterized....

tombentley added a commit that referenced this issue Feb 10, 2017

tombentley added a commit that referenced this issue Feb 10, 2017

@tombentley

This comment has been minimized.

Contributor

tombentley commented Feb 10, 2017

Metamodel references still to do

tombentley added a commit that referenced this issue Feb 13, 2017

tombentley added a commit that referenced this issue Feb 13, 2017

@tombentley

This comment has been minimized.

Contributor

tombentley commented Feb 13, 2017

Done

@tombentley tombentley closed this Feb 13, 2017

@gavinking

This comment has been minimized.

Contributor

gavinking commented Feb 13, 2017

Thanks Tom!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment