Skip to content

Add an immutable array type #5885

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

Merged
merged 13 commits into from
Feb 23, 2019
Merged

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Feb 9, 2019

So far, it's called scala.IArray[T]. I am not super happy with the name but could not come up with anything better yet.

It's an opaque alias of Array[T] that only exposes the apply and length methods.

Still missing: Wrappers that add all sequence ops to IArrays. We should upgrade to the new collections before we do this.

@odersky
Copy link
Contributor Author

odersky commented Feb 9, 2019

Btw, the first lines of IArray.scala af2a0e6 are a great showcase how opaque types, implied instances, extension methods, toplevel definitions, and inline can work together to give something beautiful.


val xs = IArray(1, 2, 3)

def f[T](ys: IArray[T]) = {
Copy link
Contributor

@julienrf julienrf Feb 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What type does this method erase to? f(ys: Array[AnyRef])? Or f(ys: AnyRef)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's Object. Just what Array[T] erases to.

@odersky
Copy link
Contributor Author

odersky commented Feb 11, 2019

I tried to make IArray covariant, using

opaque type IArray[+T] = Array[_ <: T]

Unfortunately, that runs into problems when it comes to class tags. I get:

[error] 30 |  def concat[T: ClassTag](xss: IArray[T]*): IArray[T] = Array.concat(xss: _*)
[error]    |                                                                             ^
[error]    |                              No ClassTag available for Array[_ <: T]#T'
[error]    |                              
[error]    |                              where:    T  is a type in method concat
[error]    |                                        T' is a type in class Array
[error] one error found

Indeed, there's no way to create an Array[_ <: T]. There are probably ways around this, using casts. But it makes me wary to try this as the official definition of IArray. IArray[T] should just work out of the box, in exactly the same way Array[T] does. But, Array[T] and Array[_ <: T] are not equivalent in all contexts.

@sjrd
Copy link
Member

sjrd commented Feb 12, 2019

That shouldn't matter outside of the companion of IArray, though. Outside, the only thing that can be seen is IArray[T], not any Array[_ <: T]. We might require a few hoops inside the definition of IArray, but none of that is going to leak outside.

@odersky odersky force-pushed the add-immutable-array branch from 1783f42 to f0eb2bb Compare February 14, 2019 13:09
@odersky
Copy link
Contributor Author

odersky commented Feb 14, 2019

@sjrd Right. After adding some casts in iArray's implementation, I could make them covariant, after all. 👍

@odersky odersky force-pushed the add-immutable-array branch from 1e8f916 to 4f98732 Compare February 19, 2019 12:40
@@ -0,0 +1,3 @@
import annotation.unchecked.uncheckedVariance
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in the file name: “covariant-opaque.scala”

val bs: IArray[Double] = IArray(1.0, 2.0)
val cs: Array[Double] = bs.asInstanceOf[Array[Double]]
cs(1) = 3.0
assert(bs(1) == 3.0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also check that apply and update don’t box elements?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's harder. I believe there are ways to test it, but I don't know them. The fact that apply is an inline method means it is literally replaced by its right-hand side, so by the rules of inlining there can't be any boxing. I verified the code after erasure by looking at it to make sure that's the case.

@odersky odersky force-pushed the add-immutable-array branch 2 times, most recently from bbca7f0 to c7b0651 Compare February 22, 2019 14:12
@odersky
Copy link
Contributor Author

odersky commented Feb 22, 2019

Community build fails with:

Fetching latest Dotty nightly version...
Latest Dotty nightly build version: 0.14.0-bin-20190221-daf4ce9-NIGHTLY
[info] Set current project to squants (in build file:/tmp/3/community-build/community-projects/squants/)
[info] Forcing Scala version to 0.14.0-bin-SNAPSHOT on all projects.
[info] Reapplying settings...
[info] Set current project to squants (in build file:/tmp/3/community-build/community-projects/squants/)
[info] Updating squantsJVM...
[error] Unable to find credentials for [Sonatype Nexus Repository Manager @ oss.sonatype.org].
[warn] CLIENT ERROR: 401 Unauthorized. Check your resolvers username and password.

/cc @OlivierBlanvillain

@OlivierBlanvillain
Copy link
Contributor

Are the changes to the community build submodules in c7b0651 intentional?

Unary extension methods are inlined before the end of `extMethodApply`.
Have to take this into account when checking that the call is to
an extension method.
IArray[T] is an opaque alias for Array[T]
This gives us the right error message if we try to instantiate
an hk opaque type with `new`.
Also, add `empty` method.
@odersky odersky force-pushed the add-immutable-array branch from c7b0651 to c532d3e Compare February 22, 2019 16:15
@odersky
Copy link
Contributor Author

odersky commented Feb 22, 2019

@OlivierBlanvillain No, I discovered my error: pushed wrong submodule hashes.

Need to drop the explicit result type since apparently Array's unapplySeq type
is different between 2.12 and 2.13.
@odersky odersky force-pushed the add-immutable-array branch from a8b794c to b9decdc Compare February 23, 2019 08:46
@odersky
Copy link
Contributor Author

odersky commented Feb 23, 2019

Going to merge this now, to avoid further breakage by fast-moving infrastructure changes.

@odersky odersky merged commit 63ce36a into scala:master Feb 23, 2019
@allanrenucci allanrenucci deleted the add-immutable-array branch February 24, 2019 11:31
@biboudis biboudis added this to the 0.14 Tech Preview milestone Apr 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants