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

Deprecate empty-paren (nilary) prefix unary operator #9085

Merged
merged 3 commits into from Oct 9, 2020

Conversation

eed3si9n
Copy link
Member

@eed3si9n eed3si9n commented Jun 24, 2020

Ref scala/bug#12055

Now that auto-application is deprecated, a prefix with a nilary creates a warning that cannot be avoided while maintaining a prefix position (or permanently applying warning suppression).

This adds the following warning

deprecation.scala:4: warning: unary prefix operator definition with empty parameter list is deprecated: instead, remove () to declare as def unary_~ : Foo = this
def unary_~() : Foo = this
^
deprecation.scala:5: warning: unary prefix operator definition with empty parameter list is deprecated: instead, remove () to declare as def unary_-(implicit pos: Long) = this
def unary_-()(implicit pos: Long) = this
^

I've opted to use the term "empty-paren" as defined in https://www.artima.com/pins1ed/composition-and-inheritance.html.

Note that removing an empty parameter list from a definition does not break binary compatibility.

Under -Xsource:3, error instead.

Ref scala/bug 12055

> Now that auto-application is deprecated, a prefix with a nilary creates a warning that cannot be avoided while maintaining a prefix position (or permanently applying warning suppression).

This adds the following warning

```
deprecation.scala:4: warning: empty-paren (nilary) prefix unary operator is deprecated: instead, remove () to declare as `def unary_~ : Foo`
```

I've opted to use the term "empty-paren" as defined in https://www.artima.com/pins1ed/composition-and-inheritance.html.
@SethTisue
Copy link
Member

SethTisue commented Jun 24, 2020

tiny nitpick, I would suggest

"unary prefix operator definition with empty parameter list" over "empty-paren (nilary) prefix unary operator"

@SethTisue SethTisue added the release-notes worth highlighting in next release notes label Jun 24, 2020
@sjrd
Copy link
Member

sjrd commented Jun 25, 2020

Could you also warn when there is an empty param list followed by an implicit param list (but not if there is only the implicit param list.

For example, disallow

def unary_+()(implicit pos: Position): Tree =

but allow

def unary_+(implicit pos: Position): Tree =

This is an example taken from the Scala.js codebase where I had to make that change.

@SethTisue
Copy link
Member

SethTisue commented Jun 25, 2020

@odersky is expressing some skepticism about this over at scala/scala3#9241, see remarks there

(though in a Dotty context, it's an actual removal; here we are only deprecating, except under -Xsource:3)

@eed3si9n eed3si9n force-pushed the wip/deprecate-prefix-unary-nilary branch from fb8dd88 to 7689e41 Compare June 25, 2020 18:17
@eed3si9n eed3si9n force-pushed the wip/deprecate-prefix-unary-nilary branch from 7689e41 to 8cdf16e Compare June 25, 2020 20:12
@som-snytt
Copy link
Contributor

PSA and reminder to self, deprecation does not entail removal, it just means "not recommended." Warning suppression means there is no motivation to break it out into a clunky lint.

Lint is just a handy way of suppressing categories of warnings, or selectively enabling them. -Wconf:cat=lint-foo:s or nowarn supersedes futzing with -Xlint:-foo,_. So similarly cat=deprecation&msg=unary.

@SethTisue
Copy link
Member

@eed3si9n are you interested in continuing with this?

on the other ticket, Martin makes an argument about cost (that e.g. a spec update would be needed), and an argument about benefit (that the gain is small because you have immediate trouble at the use site anyway)

perhaps (not sure if this is the same as what @som-snytt is suggesting) this could simply be a lint and not a formal deprecation (where deprecation indicates intent to eventually remove). if it's just a lint, then the stakes are lower and no spec change is needed.

@som-snytt
Copy link
Contributor

This is not a popular opinion, but

deprecation does not entail removal, it just means "not recommended."

As policy matter, Scala deprecations have been left in place for a decade, so pragmatically that is true.

The philosophical issue is whether deprecations (or any warnings) should be emitted by the compiler. Either something is an error or it is fine. API can be marked deprecated, not syntax. Then syntax or language features that are suboptimal must be linted.

@eed3si9n
Copy link
Member Author

eed3si9n commented Oct 7, 2020

@SethTisue I don't understand the hangup here. Scala 2.x was happily ignoring parenthesis until 2.13.2, but Scala team (@dwijnand) decided to not lint, but instead add a warning upon auto-application to (non-Java-defined) methods in #8833. As a general direction I'm not opposed to #8833 (You know I love deprecations). The fallout of adding this deprecation in the patch release was that it started to break ppl's code with -Xfatal-warnings. This was reported as scala/bug#12055 in June.

What I'm doing here is simply to extend the line along the logical progression from Dale's warning. And as Som has pointed out deprecation simply means "hey, watch out." I'd be happy to keep it as a warning under -Xsource:3 if that's more appropriate.

"Oh no, the language spec needs to change" I think is a strawman (?), shifting goal post because I'm not suggesting we change the language specification. All I'm saying is as an implementation of Scala compiler we should let the library authors know that they are doing something that would make the compiler mad for their end users.

The right (and easy) thing to do here for 2.13 is to merge my PR :). If not, I'd ask #8833 to be demoted into a Scalafix lint together so we can get back to relaxed ().

Copy link
Member

@dwijnand dwijnand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree

@SethTisue SethTisue requested a review from lrytz October 7, 2020 16:39
Copy link
Member

@lrytz lrytz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@lrytz lrytz merged commit 8b9858e into scala:2.13.x Oct 9, 2020
@eed3si9n eed3si9n deleted the wip/deprecate-prefix-unary-nilary branch October 9, 2020 11:46
@dwijnand dwijnand removed the release-notes worth highlighting in next release notes label Nov 12, 2020
@som-snytt som-snytt changed the title Deprecate empty-paren (nilary) prefix unary operator Deprecate empty-paren (nullary) prefix unary operator Jan 4, 2021
@som-snytt
Copy link
Contributor

Apologies for breaking the title. Probably I woke up with a hangover on Jan 4? Just guessing.

I noticed that "empty-paren" is defined in "Programming in Scala". Also that we choose not to name it in Scala 2; it is the Voldemort of signatures, possibly because his nose is like ().

https://users.scala-lang.org/t/what-does-it-mean-parameterless/9580/3?u=som-snytt

@som-snytt som-snytt changed the title Deprecate empty-paren (nullary) prefix unary operator Deprecate empty-paren (nilary) prefix unary operator Oct 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants