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

Type inference doesn't work for implicitly converted functions #6221

Closed
scabug opened this issue Aug 12, 2012 · 8 comments
Closed

Type inference doesn't work for implicitly converted functions #6221

scabug opened this issue Aug 12, 2012 · 8 comments
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Aug 12, 2012

The Scala compiler does not infer the argument types for function expressions (e.g. x => x+1) when the function is passed to a method that requires it to be implicitly converted to another type, even though it does infer the types of other objects in a similar situation. (Thanks to Heather Miller for pointing out the second case.) For example, take a look at the attached test2.scala:

class MyFunc[-A, +B] {}

class MyCollection[A] {
  def map[B](f: MyFunc[A, B]): MyCollection[B] = new MyCollection[B]
}

class OtherFunc[-A, +B] {}

object Test {
  implicit def functionToMyFunc[A, B](f: A => B): MyFunc[A, B] = new MyFunc

  implicit def otherFuncToMyFunc[A, B](f: OtherFunc[A, B]): MyFunc[A, B] = new MyFunc

  def main(args: Array[String]) {
    val col = new MyCollection[Int]

    // Doesn't compile: error: missing parameter type for expanded function ((x$1) => x$1.toString)
    // println(col.map(_.toString)) 

    // Doesn't compile: error: missing parameter type
    // println(col.map(x => x.toString))

    // Does compile
    println(col.map((x: Int) => x.toString))
    
    // Does compile (even though type params of OtherFunc not given)
    println(col.map(new OtherFunc))
  }
}

This is a problem for cases where you want to represent functions through some richer class, or to apply a macro to function expressions passed to a set of methods. For example, in Spark, I would like to apply a macro to all closure expressions passed to map(), filter(), groupBy(), and other operations in order to properly bind variables, and I would've liked to do this through an implicit conversion macro from Function1[A, B] to ShippableFunction[A, B]. Because of this bug, this can't be done without losing type inference. It would be nice to add it in this case since it seems that the types for other objects can be inferred anyway.

@scabug
Copy link
Author

scabug commented Aug 12, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6221?orig=1
Reporter: Matei Zaharia (matei)
Affected Versions: 2.9.1, 2.10.0-M6
Attachments:

  • test2.scala (created on Aug 12, 2012 2:20:26 PM UTC, 860 bytes)

@scabug
Copy link
Author

scabug commented Aug 13, 2012

@heathermiller said:
Update on this after digging around a bit.

The following seems to happen.

In the case of col.map(new OtherFunc), the expected type of map is MyFunc[Int,?]. Meanwhile, the type parameters of OtherFunc are inferred independently of the implicit conversion to be OtherFunc[Any, Nothing].

In the case of col.map(_.toString), the expected type of map is also MyFunc[Int,?].
However, in this case, implicit search seems to try to find a conversion from Function1[<error>,<error>] to the above expected type.

-Ydebug -Ylog:typer output for the col.map(_.toString) case:

[log typer] inferring view from scala.this.Function1[<error>,<error>] to <empty>.this.MyFunc[scala.this.Int,?]
[log typer] infer view from scala.this.Function1[<error>,<error>] to <empty>.this.MyFunc[scala.this.Int,?]

In both cases, implicit search does not have an influence on inferring the type of the argument of map. This doesn't seem to be spec'd, but I agree that this would be very nice to have.

@scabug
Copy link
Author

scabug commented Aug 13, 2012

@hubertp said:
I can make it to work if MyFunc extends Function1 as even that doesn't work now (https://github.com/hubertp/scala-dev/tree/2.10.x-issue/6221) but I realize that isn't entirely what you are asking.
The implicit search involving ErrorType => ErrorType is spurious and shouldn't be happening at all.

@scabug
Copy link
Author

scabug commented Aug 13, 2012

@heathermiller said:
Awesome, I've been messing around on a fix in the same place. You're right that the ticket is phrased to address a more general problem. However, your fix works for our use case-- we would ultimately extend Function1 anyway. Though, regardless, yes, the more general implicit conversion + type inference issue actually illustrated above still remains.

@scabug
Copy link
Author

scabug commented Aug 13, 2012

Matei Zaharia (matei) said:
Hubert, if that fix can make it into some version of 2.10, that would be awesome. It would really make it much simpler to use macros to preprocess closures, which has a lot of DSL applications.

@scabug
Copy link
Author

scabug commented Aug 14, 2012

@hubertp said:
Might be a bit too late for 2.10.0, but it should make it into one of the inevitable minor 2.10 releases.

@scabug
Copy link
Author

scabug commented Jun 11, 2013

@xeno-by said:
Seems related #7187

@scabug
Copy link
Author

scabug commented Jun 12, 2013

@paulp said:
scala/scala#2650

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants