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

Are specialPolyClass ParamTypes inferable as type arguments or not? #5991

Open
scabug opened this issue Jun 28, 2012 · 6 comments
Open

Are specialPolyClass ParamTypes inferable as type arguments or not? #5991

scabug opened this issue Jun 28, 2012 · 6 comments

Comments

@scabug
Copy link

scabug commented Jun 28, 2012

(Using Manifests to avoid interacting with #5990.)

def isItInferableAsATypeArg[A : Manifest](f: A => Unit) = manifest[A]

object Repeated extends ((Int*) => Unit) {
  def apply(x: Int*) {}
}

object ByName extends ((=> Int) => Unit) {
  def apply(x: => Int) {}
}

isItInferableAsATypeArg(Repeated)
error: type mismatch;
 found   : Repeated.type
 required: Seq[Int] => Unit

Okay, so no then!

isItInferableAsATypeArg(ByName)
error: No Manifest available for => Int.

Okay, so yes then?

Somewhere in here is a bug, right?

@scabug
Copy link
Author

scabug commented Jun 28, 2012

Imported From: https://issues.scala-lang.org/browse/SI-5991?orig=1
Reporter: Ryan Hendrickson (ryan.hendrickson_bwater)
Affected Versions: 2.10.0-M4
See #4176

@scabug
Copy link
Author

scabug commented Jul 2, 2012

@adriaanm said:
interesting, the CBN is indeed inferred (from -Xprint:typer): isItInferableAsATypeArg[=> Int]

@scabug
Copy link
Author

scabug commented Jul 2, 2012

@adriaanm said:
Feel free to repeatedly assign back to me.

@scabug
Copy link
Author

scabug commented Jul 2, 2012

@retronym said (edited on Jul 2, 2012 8:33:38 PM UTC):
In total, the solution(s) to #4176 leave us in a situation where we can write:

object Repeater extends ((Int*) => Unit) {
  def apply(x: Int*) {}
}

but not do much more with it; it is treated as a subtype of Seq\[Int\] => Unit

More discussion over at #6016.

It might be prudent to disallow * in non method types altogether.

=>A hasn't suffered the same scrutiny. It remains expressible in function types (and it's pretty commonly used as such):

scala> def f(a: (=> Any) => Any) = a(???)
f: (a: => Any => Any)Any

scala> f(x => 0)
res1: Any = 0

Eta expansion retains the by-name-ness:

scala> def foo(z: Any)(a: => Int) = z
foo: (z: Any)(a: => Int)Any

scala> (foo(0) _)(???)
res2: Any = 0

So I'm not sure where to take this. If we're going to follow through with the tough stance on *, we should do it completely. But we should also have a clear story about why we have different rules for =>.

@scabug
Copy link
Author

scabug commented Jul 3, 2012

@adriaanm said (edited on Jul 3, 2012 4:23:12 PM UTC):
The principled stand is that we should never have let ByNameParamClass or RepeatedParamClass symbols leak into user-visible TypeRefs

Instead, when eta-expanding, we should desugar them into the appropriate instantiations of FunctionN, or possibly a subclass such as ByNameFunction and VarargFunction.

Unfortunately we don't have the resources to fix this right now.

@som-snytt
Copy link

@SethTisue maybe close

It might be prudent to disallow * in non method types altogether.

Prudence prevailed.

=>A hasn't suffered the same scrutiny.

The behavior under eta-expansion was added to the spec.

It's possible that by-name as parameterless method type is sufficiently explanatory. The spec doesn't have to say (as everyone thinks to themselves) that passing the arg "really creates a function () => A"; it's really the reference to x that induces the conversion to a function type, where for paramless it means invocation.

On the question, how are => A and A* different, as they are just a prefix and a suffix to the type of a parameter? The difference is that the type of a repeated param ("inside") is Seq[A], and passing it as a repeated arg requires xs: _*. Then the remaining extraordinary behavior is eta-expanding f(xs: A*) rather than requiring

List(List(1,2,3,4)).map(f(_: _*))

@scala scala deleted a comment from scabug Aug 19, 2023
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

3 participants