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

Replace static forwarders by a non-$ method to get the module #573

Closed
lrytz opened this issue Nov 2, 2018 · 12 comments
Closed

Replace static forwarders by a non-$ method to get the module #573

lrytz opened this issue Nov 2, 2018 · 12 comments

Comments

@lrytz
Copy link
Member

lrytz commented Nov 2, 2018

While fixing the issues with static forwarders, @retronym suggested we should stop emitting those forwarders and instead emit a single static method to access the companion module.

Proposal:

  1. Add the static method in 2.13 (object A generates public static A$ module() { return A$.MODULE$ } in class A)
  2. Deprecate static forwarders - in 2.13 already?
  3. Remove static forwarders - in 2.14 already?

Opinions? Did we discuss this before?

@SethTisue
Copy link
Member

SethTisue commented Nov 2, 2018

I don't recall this ever being proposed before.

I'm rather hesitant about this change. (Maybe I need time to get used to the idea, since it's new to me.)

If we want to make a change in this area, I would suggest not deprecating and not removing, but making them opt-in via a compiler flag. But even that, I'm hesitant about. I think we'd need to discuss it on https://contributors.scala-lang.org and see what the community thinks.

I used static forwarders all the time when I worked on a large mixed Java/Scala codebase. It's one of the features that makes it not just possible, but convenient for Java users to start sneaking Scala code into mixed codebases, or to write Scala libraries that are usable from Java without annoying the Java clients with extra ceremony.

Making the forwarders opt-in would reduce the harm in those scenarios, but it wouldn't remove it, because what if you don't control the Scala code in question, you have to ask the author to enable the forwarders, if it isn't the default.

What about making the forwarders opt-out, so there's an escape hatch in cases where they're getting in the way? Thinking out loud.

@SethTisue
Copy link
Member

Also, I've never been personally been bitten by a static forwarder, I haven't personally experienced the downside. In order to justify the change to the community, I think you and/or Jason would need to be explicit about what the downsides of forwarders are.

@lrytz
Copy link
Member Author

lrytz commented Nov 2, 2018

I've never been personally been bitten by a static forwarder

you and/or Jason would need to be explicit about what the downsides of forwarders are

You might be on the right track here: these forwarders are a bit annoying from our perspective, selecting the right methods is a bit of a struggle. So maybe they look worse with the compiler writer's bias.

@SethTisue
Copy link
Member

one further thought: we might ask within Lightbend if the static forwarders are considered valuable by Akka, Play, Lagom, etc, they're the biggest users of Scala-for-Java-consumption

@lrytz
Copy link
Member Author

lrytz commented Nov 2, 2018

Good idea. cc @patriknw, @marcospereira, @ignasi35. To summarize, currently object A { def f = 1 } generates (approximately)

class A$ {
  public static A$ MODULE$ = new A$;
  public int f() { return 1; }
}
class A {
  public static int f() { return A$.MODULE$.f(); }
}

So Java clients can write A.f(). The proposal is to only emit a single static method in A, so java clients would have to write A.module().f().

@SethTisue
Copy link
Member

You mean A.module().f()? (static "method"?)

@lrytz
Copy link
Member Author

lrytz commented Nov 2, 2018

right, fixed!

@patriknw
Copy link

patriknw commented Nov 2, 2018

@lrytz We use A.f() all the time in Java APIs. Having to use A.module().f() is not an option in my opinion. That would be very inconvenient and leaking a technical Scala detail into user api.

@dwijnand
Copy link
Member

dwijnand commented Nov 2, 2018

It's common in Java to have a static method or field to access the instance of a singleton, like:

Foo.INSTANCE.doThing();

(There are various implementations for singletons in Java, I think Effective Java explains them).

In Akka there seems to be some precedence of defining getInstance for Java users.

For true static methods, for Java or other reasons, SIP-30 is relevant:

https://docs.scala-lang.org/sips/static-members.html

@dragos
Copy link

dragos commented Nov 3, 2018

Would this single-out main and still emit a static forwarder for this one?

@SethTisue
Copy link
Member

@lrytz shall we close this?

@retronym
Copy link
Member

Yeah, seems like this isn't really feasible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants