Skip to content
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

Add lazyZip to ArrayOps and StringOps #11063

Closed
julienrf opened this issue Aug 9, 2018 · 4 comments
Closed

Add lazyZip to ArrayOps and StringOps #11063

julienrf opened this issue Aug 9, 2018 · 4 comments

Comments

@julienrf
Copy link

julienrf commented Aug 9, 2018

The lazyZip operation is currently only available on Iterable. To use it on an Array or a String you have to first convert them to iterables. The lazyZip operation should be available on Array and String without requiring this conversion.

@szeiger
Copy link

szeiger commented Aug 9, 2018

A more generally applicable definition would be to put toLazyZipOps into Predef and make use of IsIterableLike. I was going to make the argument that it is unnecessary overhead for Array and String because they are strict but actually that doesn't even matter. LazyZipOps forces its argument, there are no by-name tricks to prevent that, so why does it exist in the first place? Shouldn't lazyZip be defined as a method directly on Iterable?

@szeiger
Copy link

szeiger commented Aug 9, 2018

Context for lazyZip: scala/collection-strawman#223

@szeiger szeiger self-assigned this Aug 9, 2018
@julienrf
Copy link
Author

julienrf commented Aug 9, 2018

Shouldn't lazyZip be defined as a method directly on Iterable?

The problem is that you would then be able to chain lazyZip too many times. Consider the following expressions:

def example(xs: List[Int]): Unit = {
  (xs lazyZip xs): LazyZip2[Int, Int, List[Int]]
  // `LazyZipN` types are special lazy collection types
  // We can go up to LazyZip4
  (xs lazyZip xs lazyZip xs lazyZip xs): LazyZip4[Int, Int, Int, Int, List[Int]]
  // After that, you get a compilation error
  xs lazyZip xs lazyZip xs lazyZip xs lazyZip xs
  // error: method lazyZip is not a member of LazyZip4
}

However, note that there is an implicit conversion from LazyZipN[E1, E2, ...] to Iterable[(E1, E2, …)]. If lazyZip was defined as a method on Iterable, it would become possible to call lazyZip on a LazyZip4 instance:

(xs lazyZip xs lazyZip xs lazyZip xs lazyZip xs): LazyZip2[(Int, Int, Int, Int), Int, List[(Int, Int, Int, Int)]]
// We would get a LazyZip*2* instance instead of an expected LazyZip5 (which does not exist)

In order to make it impossible to call lazyZip on a LazyZip4 instance, the lazyZip method is available via an implicit conversion from Iterable. As a consequence, it is possible to call it on an Iterable instance, but not on something that can be converted into an Iterable (such as a LazyZip4 instance).

@julienrf
Copy link
Author

julienrf commented Aug 9, 2018

A more generally applicable definition would be to put toLazyZipOps into Predef and make use of IsIterableLike

Yes, that’s a good suggestion!

szeiger added a commit to szeiger/scala that referenced this issue Aug 9, 2018
- Also simplify the definition of lazyZip for collections. There is no
  need for extension methods and LazyZipOps. lazyZip can be defined
  as a regular method.
- This alone makes it available for Array and String types but we want
  to get back an Array or String (if applicable) so we still need
  separate definitions in ArrayOps and StringOps.

Fixes scala/bug#11063
@szeiger szeiger added the has PR label Aug 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants