I’m wondering why this compiles and runs. Is it related to omitting parentheses Feature maybe?
Welcome to the Ammonite Repl 1.1.2
(Scala 2.12.6 Java 1.8.0_172)
If you like Ammonite, please support our development at www.patreon.com/lihaoyi
@ def test(n: Unit): Int = 32
defined function test
@ test(1111)
res1: Int = 32
@ test("blabla")
res2: Int = 32
It is obviously a contrived example. I don’t understand why that works, can maybe someone tell me what the compiler does here?
Implicit conversions can be applied to expressions whose type does not match their expected type, […]
If e has some value type and the expected type is Unit, e is converted to the expected type by embedding it in the term { e; () }.
EDIT, if you don’t like this feature, consider compiling under -Ywarn-value-discard
Thank you for your answer. Sorry that I wasn’t clear. You guessed correctly, I was assuming that I could not put an Int as an argument into a method that expects a unit.
Thank you for pointing me to the relevant spec. I was not aware of this specific implicit conversion.
Personally, I consider this a bit of a misfeature, and the fewer of these “you probably meant x let me silently do that for you” features the better IMO, but opinions tend to differ on that - if it were up to me, the language wouldn’t have overloading or call-by-name either (at least in its current form), and there are very few people who agree with me on that I think
I see that it is useful to have a parameter of type Unit. I meant
actually why it is allowed to call a method with an argument that has
different type than the defined parameter. I came across this having a f(a: A) where A was Unit in one case. I wasn’t aware that any
value is converted to Unit implicitly and that puzzled me. I tried to
explain it to myself, trying for example with the omitting-parentheses
syntax, but failed…. Well, now that I know it is due to an implicit
conversion, I should have guessed something like that
scala> class Foo { def foo(u: Unit) = u }
defined class Foo
scala> :javap -filter -cp Foo
Compiled from "<console>"
public class Foo {
public void foo(scala.runtime.BoxedUnit);
Code:
0: return
public Foo();
Code:
0: aload_0
1: invokespecial #23 // Method java/lang/Object."<init>":()V
4: return
}