Skip to content

Rewrite breakout #46

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

Closed
MasseGuillaume opened this issue Jun 19, 2018 · 13 comments
Closed

Rewrite breakout #46

MasseGuillaume opened this issue Jun 19, 2018 · 13 comments
Milestone

Comments

@MasseGuillaume
Copy link
Contributor

MasseGuillaume commented Jun 19, 2018

seen in:
https://github.com/kxbmap/configs/pull/30/files#diff-8416f81bdac5bf53701680a5968a0f9eL226

input:

import scala.collection.breakOut
val map : Map[Int,String] = List("London", "France").map(x => (x.length, x))(breakOut)

output:

val map : Map[Int,String] = List("London", "France").map(x => (x.length, x)).toMap
@julienrf
Copy link
Contributor

Well, the output is not semantically equivalent to the input since it creates an intermediate List.

@julienrf
Copy link
Contributor

I think the rule should work as follows.

  • Eligible methods are: map, flatMap, collect, ++, ++:, scanLeft, scanRight, zip and zipWithIndex,
  • Any call of the form .<op>(collection.breakOut) (where <op> is a call of one of the aforementioned operations, e.g. map(f), zipWithIndex), should be replaced with .iterator.<op>.to(implicitly[Factory[<A>, <C>]]), where <A> and <C> are the two and third type parameters of the CanBuildFrom instance returned by collection.breakOut.

For instance, if one writes:

List(1, 2, 3).map(_ + 1)(collection.breakOut): Set[Int]

Which instantiates breakOut’s type parameters like so:

List(1, 2, 3).map(_ + 1)(collection.breakOut[List[Int], Int, Set[Int]]): Set[Int]

We should produce:

List(1, 2, 3).iterator.map(_ + 1).to(implicitly[Factory[Int, Set[Int]]])

@MasseGuillaume
Copy link
Contributor Author

would this works too?

List(1, 2, 3).iterator.map(_ + 1).to(implicitly)

@julienrf
Copy link
Contributor

You should just try:

Welcome to Scala 2.13.0-M4 (OpenJDK 64-Bit Server VM, Java 1.8.0_171).
Type in expressions for evaluation. Or try :help.

scala> List(1, 2, 3).iterator.map(_ + 1).to(implicitly): Set[Int]
res0: Set[Int] = ChampHashSet(2, 3, 4)

It seems to be working, yes!

@MasseGuillaume
Copy link
Contributor Author

@julienrf I know, I mean does this work in the general case for migrations. The implicit Factory could be a bit different than the CanBuildFrom.

@julienrf
Copy link
Contributor

It seems to be enough: the type of the required implicit Factory seems to be correctly inferred by the compiler based on the expected result type.

@MasseGuillaume
Copy link
Contributor Author

@julienrf

val xs = List("London", "France")
def f(x: String): (Int, String) = (x.length, x)
val map = xs.iterator.map(f).to(implicitly)
val map2: Map[Int, String] = xs.iterator.map(f).to(implicitly)

10:35: type mismatch;
[error]  found   : Nothing <:< Nothing
[error]  required: scala.collection.Factory[(Int, String),?]
[error]   val map = xs.iterator.map(f).to(implicitly)
[error]                                   ^

@julienrf
Copy link
Contributor

The line:

val map = xs.iterator.map(f).to(implicitly)

Is not representative of the way breakOut is supposed to be used: the result type must be known by the compiler rather than being inferred by a “default” CanBuildFrom instance.

Therefore I suggest ignoring that case for now.

@MasseGuillaume
Copy link
Contributor Author

ok, we ignore the following:

import scala.collection.breakOut
val xs = List("London", "France")
def f(x: String): (Int, String) = (x.length, x)
val map = xs.map(f)(breakOut)
// map: scala.collection.immutable.IndexedSeq[(Int, String)] = Vector((6,London), (6,France))

@MasseGuillaume
Copy link
Contributor Author

MasseGuillaume commented Jun 27, 2018

no solution

  • dequeueAll (does not take an implicit Factory)
  • Map.transform (does not take an implicit Factory)
  • scan (should be deprecated ?)

view

  • +:
  • :+
  • ++:
  • updated

iterator

reverse-iterator

  • reverseMap

@MasseGuillaume
Copy link
Contributor Author

@julienrf

for operators that take collections such as ++ or zip, do we apply .iterator as well to the rhs ?

-lhs.zip(rhs)(breakOut): Array[(Int, Int)]
+lhs.iterator.zip(rhs.iterator).to(implicitly): Array[(Int, Int)]

@julienrf
Copy link
Contributor

No.

@SethTisue
Copy link
Member

List(1, 2, 3).iterator.map(_ + 1).to(implicitly)

ha, cool

julienrf added a commit that referenced this issue Jun 29, 2018
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

No branches or pull requests

3 participants