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

2.13: confusing error when using infix for nullary method #11461

Open
lrytz opened this Issue Apr 1, 2019 · 12 comments

Comments

Projects
None yet
5 participants
@lrytz
Copy link
Member

commented Apr 1, 2019

In 2.12:

scala> class A { def foo() = 0 }
defined class A

scala> (new A) foo ()
res4: Int = 0

In 2.13:

scala> class A { def foo() = 0 }
defined class A

scala> (new A) foo ()
               ^
       error: no arguments allowed for nullary method foo: ()Int

@SethTisue SethTisue added this to the 2.13.1 milestone Apr 1, 2019

@som-snytt

This comment has been minimized.

Copy link

commented Apr 2, 2019

Why would you apply unit value to a method that takes no params? The message makes perfect sense if you have drunk no kool-aid.

If someone is confused, maybe -Xlint:defuse to detect the infix and unit value arg and nuance the message. Or just nuance for the case of unit and nullary method. a.f(()) would result in the same advice.

@ritschwumm

This comment has been minimized.

Copy link

commented Apr 3, 2019

how else would i call a nullary method like this in no-dots/dsl syntax?

@som-snytt

This comment has been minimized.

Copy link

commented Apr 3, 2019

@ritschwumm That is called postfix, not infix.

@ritschwumm

This comment has been minimized.

Copy link

commented Apr 3, 2019

calling def foo = 0 as obj foo would be postfix, which has been deprecated for a long time now.
calling def foo() = 0 as obj foo () always counted as infix.

@som-snytt

This comment has been minimized.

Copy link

commented Apr 3, 2019

That was a bug. The spec: "The right-hand operand of a left-associative operator may consist of several arguments enclosed in parentheses...".

There is no deprecation, although the feature doc is persuasive: "Postfix notation is preserved for backward compatibility only. Historically, several DSLs written in Scala need the notation."

scala> object X { def f() = 42 }
defined object X

scala> X f ()
         ^
       error: no arguments allowed for nullary method f: ()Int

scala> X f
         ^
       error: postfix operator f needs to be enabled
       by making the implicit value scala.language.postfixOps visible.
       This can be achieved by adding the import clause 'import scala.language.postfixOps'
       or by setting the compiler option -language:postfixOps.
       See the Scaladoc for value scala.language.postfixOps for a discussion
       why the feature needs to be explicitly enabled.

scala> import scala.language.postfixOps
import scala.language.postfixOps

scala> X f
res3: Int = 42

scala> X.f
res4: Int = 42

scala> object X { def f(u: Unit*) = 42 }
defined object X

scala> X f
         ^
       error: missing argument list for method f in object X
       Unapplied methods are only converted to functions when a function type is expected.
       You can make this conversion explicit by writing `f _` or `f(_)` instead of `f`.

scala> X f ()
res6: Int = 42

@ritschwumm

This comment has been minimized.

Copy link

commented Apr 3, 2019

so dotless DSL syntax is effectively dead now, except when you are lucky and all methods involved take exactly one parameter in one parameter list? maybe it should be removed altogether then, simplifying the grammar some more...

@som-snytt

This comment has been minimized.

Copy link

commented Apr 3, 2019

Alternatively, someone could propose a new feature, "unit value discard," as vengeance for "value discard," to apply just for this case, discarding unit value when no value is expected in a param list. (Note that no value is not Nothing here.)

Meantime, the PR avoids advanced DSL gymnastics and simply suggests:

scala> object X { def f() = 42 }
defined object X

scala> X f ()
         ^
       error: can't supply unit value with infix notation because nullary method f: ()Int takes no arguments; use dotted invocation instead: X.f()
@som-snytt

This comment has been minimized.

Copy link

commented Apr 8, 2019

Unit value discard is proposed at scala/scala#7973

@Jasper-M

This comment has been minimized.

Copy link
Member

commented Apr 9, 2019

If you want to design a DSL that allows you to write this, you still can:

scala> object X { def f(u: Unit) = 42 }
defined object X

scala> X f ()
res3: Int = 42

Only now it's actually consistent. Now only a b (c, d) should always mean a.b((c, d)) and we're done...

@lrytz

This comment has been minimized.

Copy link
Member Author

commented Apr 9, 2019

@SethTisue

This comment has been minimized.

Copy link
Member

commented Apr 9, 2019

LOL

Som already improved the description on scala/scala#7684, I have improved the title and also made the change in dem Release-Notes auf GitHub 🇩🇪

@som-snytt

This comment has been minimized.

Copy link

commented Apr 9, 2019

I see the unimproved title was translated directly in the foreign press. Now I wish I had come up with a good pun for it. On gitter yesterday, I said, In loco parenthesis.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.