Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add @static SIP#491

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
jvican merged 4 commits intoscala:masterfromDarkDimius:master
Nov 25, 2016
Merged

Add @static SIP#491

jvican merged 4 commits intoscala:masterfromDarkDimius:master
Nov 25, 2016

Conversation

@DarkDimius
Copy link
Contributor

Add @static SIP

Copy link
Member

Choose a reason for hiding this comment

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

Comparison

DarkDimius added a commit to dotty-staging/dotty that referenced this pull requestMar 7, 2016
This pull request implements most of machinery needed forscala/docs.scala-lang#491Only 3-rd check is not implemented by this commit.I propose to get this in faster tofixscala#1149
DarkDimius added a commit to dotty-staging/dotty that referenced this pull requestMar 7, 2016
This pull request implements most of machinery needed forscala/docs.scala-lang#491Only 3-rd check is not implemented by this commit.I propose to get this in faster tofixscala#1149
@DarkDimius
Copy link
ContributorAuthor

The implementation was merged into Dotty.


For example, classes extending `android.os.Parcelable` are required to have a static field named `CREATOR` of type `android.os.Parcelable$Creator`.

Another example is using an [`AtomicReferenceFieldUpdater`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.html).
Copy link
Member

@janekdbjanekdbApr 20, 2016
edited
Loading

Choose a reason for hiding this comment

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

s/7/8/ ?

@kjsingh
Copy link

why can't we have static as a keyword?

@sjrd
Copy link
Member

Because adding new keywords breaks existing code that used them as identifiers. Adding keywords must be donevery sparingly, only when there is no other option.

Adowrath, tamchow, and pharrington reacted with thumbs up emoji

@kjsingh
Copy link

I guess libs doing interop with Java code will be avoiding that.

@jvican
Copy link
Member

@DarkDimius is there any change you want to do here before the SIP review?

@DarkDimius
Copy link
ContributorAuthor

I guess libs doing interop with Java code will be avoiding that.

Why would they? You may want some data to be seen as Java static field, and you can use@static for this.

@DarkDimius
Copy link
ContributorAuthor

@DarkDimius is there any change you want to do here before the SIP review?

@jvican, I've applied those changes now and cleared git history. Feel free to merge if it looks good.

@jvican
Copy link
Member

Great changes, let's merge it for next week's discussion.

@jvicanjvican merged commit53f10e5 intoscala:masterNov 25, 2016
@xuwei-k
Copy link
Contributor

#635

@adriaanm
Copy link
Contributor

  • I don't think it's a good idea to let code gen depend in non-obvious ways on an annotation. Can we break this down further? How about....
    • Always emit object members as class statics, as suggested by Martin (solves initialization mismatch that killedImplement @static annotation on singleton object fields. scala#894, and keeps static members out of class, which would be problematic in our type system)
    • Deal with name clashes using an@exportedName annotation?
    • Allow emitting apublic static field without accessor using@suppressAccessors?

The proposal should go into more detail on:

  • What about binary compat (adding/removing@static annotation)
  • Interaction with initialization semantics?

Some relevant bugs:

@retronym
Copy link
Member

retronym commentedFeb 15, 2017
edited
Loading

I'd like to see the "Compilation scheme" section fleshed out. Currently, it talks about how this would fit into the compiler pipeline, but lacks details about how things would be compiled to bytecode.

Here's an example I'm interested in:

packagep1;objectC {@staticvalfoo:AnyRef=C;valbar:AnyRef=C }

If I translate this according to the intuitive description herein, taking a few guesses at the details, I start with:

publicclassTest {publicstaticvoidmain(String[]args) {System.out.println(C$.MODULE$.foo());// null  }}classC {publicstaticfinalObjectfoo;static {foo =C$.MODULE$;// initializer moved to CompanionClass.<clinit>  }}finalclassC$ {publicstaticC$MODULE$;privatefinalObjectbar;publicstaticObjectfoo() {returnC.foo; }static {Objectx =C.foo;// or UNSAFE.ensureClassInitialized(classOf[C])newC$();  }privateC$() {super();MODULE$ =this;bar =this;  }}

Running this printsnull. I guess we should move the call toC.<init> after the super constructor call and the assignment of the module var:

finalclassC$ {publicstaticC$MODULE$;privatefinalObjectbar;publicstaticObjectfoo() {returnC.foo; }static {newC$();  }privateC$() {super();MODULE$ =this;Objectx =C.foo;// or UNSAFE.ensureClassInitialized(classOf[C])bar =this;  }}

Which avoids the NPE.

But in that case, triggeringC.<clinit> beforeC$.<clinit> would reverse the order that the initalizer forfoo and the super constructor of the module class is run.

Both of these variations have another drawback: References toC in the RHS of static initializers introduce a cyclic dependency betweenC.<clinit> andC$.<clinit>. This is deadlock prone if a a pair of threads simultaneously statically initialize the class and module class.

So maybe we instead should put leave all the initalization code in the module class?

classC {publicstaticObjectfoo;// can't be final}finalclassC$ {publicstaticC$MODULE$;privatefinalObjectbar;publicstaticObjectfoo() {returnC.foo; }static {newC$();  }privateC$() {super();MODULE$ =this;C.foo =this;bar =this;  }}

This looks more promising for thread-safe initialization, and preserving semantics. But we are no unable to declarefoo as final, which is a bit of a drag, because one reason you want to make a field static is to hold a method handle "constant", and hotspot only is able to fully inline invocations through that handle if the field is markedfinal. (Or, if it has the JDK internal annotation,java.lang.invoke.Stable, which isn't in our box of tricks.)

@lrytz
Copy link
Member

We could also consider omitting the accessor methods for@static fields and emitting direct accesses to the field.

@DarkDimius
Copy link
ContributorAuthor

classC {publicstaticObjectfoo;static {foo =C$.MODULE$;  }}finalclassC$ {publicstaticC$MODULE$;privatefinalObjectbar;publicstaticObjectfoo() {returnC.foo; }static {newC$();  }privateC$() {super();MODULE$ =this;Objectx =C.foo;// or UNSAFE.ensureClassInitialized(classOf[C])bar =this;  }}

Is the proposed desugaring.

@retronym

I guess we should move the call toC.<init> after the super constructor call and the assignment of the module var:

I guess you've meantC.<clinit>. Than that's true.

But in that case, triggeringC.<clinit> beforeC$.<clinit> would reverse the order that the initalizer for foo and the super constructor of the module class is run.

C$.<clinit> isn't user defined. Did you meanC$.<init>?

In case you did, the order in which initializer for foo and the super constructor of the module class is run indeed may change under the proposed sip. It's discussed herehttps://github.com/scala/scala.github.com/pull/658/files#diff-9284321b7900073f358a16a971c06881R159 , do you want me to expand this discussion?

This is deadlock prone if a a pair of threads simultaneously statically initialize the class and module class.

If we always trigger initialization ofC.<clinit> fromC$.<init> we will introduce ordering here that should help. But in case user-code inherently has cycles in inititaliziation, I don't think we can do anything.

Thanks for the questions, I'll expand the "Compilation scheme" section.

@retronym
Copy link
Member

do you want me to expand this discussion?

Yes, it would be useful to talk about the super constructor thing explicitly,
perhaps with an example showing how the order could vary depending on how
whether the class or module was initialized first.

If we always trigger initialization of C. from C$. we will
introduce ordering here that should help. But in case user-code inherently
has cycles in inititaliziation, I don't think we can do anything.

I still think that we're introducing a new form of cycle by moving
the code into 'C$'-s static initializer, but I guess that's what the user
is asking for with this annotation, so we can argue that it is the user's
responsibility to code around this possibility.

```java
{% highlight java %}
class Foo {
public static int x = 5;

Choose a reason for hiding this comment

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

shouldn't this be final?

Copy link
Member

Choose a reason for hiding this comment

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

yes

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@SethTisueSethTisueSethTisue left review comments

+1 more reviewer

@kjsinghkjsinghkjsingh left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

11 participants

@DarkDimius@kjsingh@sjrd@jvican@xuwei-k@adriaanm@retronym@lrytz@SethTisue@dwijnand@janekdb

[8]ページ先頭

©2009-2025 Movatter.jp