4
private val alwaysTrue = (_, _) => true

Causes the compiler to complain that it needs the types for both _'s. Why? They're just discarded anyway, shouldn't they be inferred to be Scala.Any?

MushinNoShin
  • 4,695
  • 2
  • 32
  • 46
  • maybe see this http://stackoverflow.com/questions/25778616/what-is-the-use-cases-of-ignored-variable-syntax-in-scala – Zee Aug 05 '15 at 20:57
  • Also it doesn't necessarily need types, but names. `private val alwaysTrue = (test: _, test1: _) => true` works fine. – thwiegan Aug 05 '15 at 21:00
  • So it's not really don't care inputs then? It's... something else? The compiler error specifically stated types (and adding types to them makes it happy), I'm curious why it couldn't do that itself. – MushinNoShin Aug 05 '15 at 21:01
  • Afaik scala function parameters need always to be typed, since scala is statically typed and must derive them from somewhere. So I suppose the compiler enforces types at least on parameters. This works as well btw: `private val alwaysTrue = (_: _, _: _) => true`. So apparently it does not matter what type, as long as they are typed. – thwiegan Aug 05 '15 at 21:06
  • Yeah, I get that it needs it, but why? It seems so trivial, we even agree that `_`'s will not be used in the function body (except for the special case where we don't declare parameters). The type should obviously be the root type, which I believe is `Scala.Any` (for some reason I remember it being `Nothing`, but that seems perhaps outdated knowledge). – MushinNoShin Aug 05 '15 at 21:11
  • Oh, wait, perhaps the type inference doesn't default to the most general case when there aren't any constraints? I still wonder why, and this is just a guess on my part anyway. – MushinNoShin Aug 05 '15 at 21:13

1 Answers1

1

You must explicitly provide the parameter types for anonymous functions, unless something else expects a specific type--in which case the compiler will try to infer that type, if it can. It's in the SLS 6.23 :

If the expected type of the anonymous function is of the form scala.Functionn[S1,…,Sn, R], the expected type of e is R and the type Ti of any of the parameters xi can be omitted, in which caseTi = Si is assumed. If the expected type of the anonymous function is some other type, all formal parameter types must be explicitly given, and the expected type of e is undefined.

I'm reading between the lines just a bit, but there is no expected type, so you must explicitly provide the types.

private val alwaysTrue = (_: Any, _: Any) => true

In cases where you have something like List(1, 2, 3).filter(_ > 3), the expected type is Int => Boolean, so it isn't necessary to provide the parameter type.

Michael Zajac
  • 55,144
  • 7
  • 113
  • 138
  • Please don't take this as rude, but I'm very curious as to why the spec requires that. It seems to be a very obvious conclusion to draw as to what the types should be. – MushinNoShin Aug 05 '15 at 21:16
  • 1
    @MushinNoShin We can all speculate.. but generally when things are inferred as `Any` that's a symptom of some other problem, so it's avoided. – Michael Zajac Aug 05 '15 at 21:17
  • Put it this way. If it were to try to infer the type, without hints, it would *always* infer `(Any, Any) => A`. When will that ever be useful? Answer: Almost never. – Michael Zajac Aug 06 '15 at 01:40
  • In the absence of any constraints on the types, Any seems completely valid. If it can't be constrained at all, then Any is fine. It's obvious that as an input into a function it's not useful, it's being discarded. The utility comes from being able to discard it and return a boolean. This still doesn't answer "why not" outside of a simple "because the spec says so". I'm curious why that decision was made for the spec, is it to make the implementation easier? – MushinNoShin Aug 06 '15 at 15:32
  • @MushinNoShin And I'm saying the answer outside of the spec is that *it is not useful*. A method that accept `Any` parameters isn't likely to have much utility. A method that discards parameters and always returns true isn't very useful either. Why change the spec for such rare use cases, when inferring `Any` would most likely be the result of an error anyway? – Michael Zajac Aug 06 '15 at 15:37
  • I found a use for it, therefore, it is useful. – MushinNoShin Aug 06 '15 at 15:43
  • That doesn't mean it is useful for *everyone* and requires a change to the spec. – Michael Zajac Aug 06 '15 at 15:48
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/85321/discussion-between-mushinnoshin-and-m-z). – MushinNoShin Aug 06 '15 at 16:18