- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Support @static annotation to create static fields or methods.
Tue, 2011-05-17, 14:00
I want to suggest that a new annotation @static will be added to core
Scala. Methods or fields annotated with @static will be generated as
static in bytecode.
There are several reasons I can think of:
1. Some frameworks require static fields. In Android, a class
implementing the Parcelable interface is required to have a static
CREATOR field
2. Uniformity: with @static, we can remove the @SerialVersionUID
annotation.
3. Completeness/Political: Having this annotation will close a "hole" in
Scala of a capability that exists in the JVM but cannot be written in
Scala.
The common replyto such suggestions is "write this part in Java". But
then it means I have to setup dual compilation of both Java and Scala in
my module. Furthermore, the class that needs such a field may have
non-trivial code, or maybe it needs to use other Scala classes which is
sometimes tricky (e.g., you can't use the collection classes as-is in Java).
Regards,
Ittay
Tue, 2011-05-17, 15:27
#2
Re: Support @static annotation to create static fields or metho
On 17 May 2011 15:00, Ittay Dror <ittay.dror@gmail.com> wrote:
The common replyto such suggestions is "write this part in Java". But then it means I have to setup dual compilation of both Java and Scala in my module. Furthermore, the class that needs such a field may have non-trivial code, or maybe it needs to use other Scala classes which is sometimes tricky (e.g., you can't use the collection classes as-is in Java).
Don't see the problem you have with the 'write this part in Java' solution, if want to use Scala collections, why not use the Java class simply as a wrapper and call a Scala singleton when needed ?
It must not be that tricky if you use the Java class as a simple wrapper.
Regards,
Ittay
--
Alois Cochardhttp://aloiscochard.blogspot.comhttp://twitter.com/aloiscochard
Tue, 2011-05-17, 15:37
#3
Re: Support @static annotation to create static fields or metho
On Tue, May 17, 2011 at 4:07 PM, Rex Kerr <ichoran@gmail.com> wrote:
+1That observation actually would point to a different solution:
And,
4. Performance. The JVM can optimize static fields better than it can non-static fields when code is complex.
1) Make all fields and methods of top-level objects static
2) use name mangling if these static fields conflict with a companion class member (as they would otherwise be rejected by the verifier)
3) Add forwarders to static fields from the module object.
The advantage is that the Scala code generator does not need to dereference $MODULE fields
when accessing object members.
Another advantage is that @static would not be needed at all.
Cheers
-- Martin
Tue, 2011-05-17, 15:47
#4
Re: Support @static annotation to create static fields or metho
+1
Way better to see this handled automatically by the compiler than using specific annotation !
On 17 May 2011 16:18, martin odersky <martin.odersky@epfl.ch> wrote:
--
Alois Cochardhttp://aloiscochard.blogspot.comhttp://twitter.com/aloiscochard
Way better to see this handled automatically by the compiler than using specific annotation !
On 17 May 2011 16:18, martin odersky <martin.odersky@epfl.ch> wrote:
On Tue, May 17, 2011 at 4:07 PM, Rex Kerr <ichoran@gmail.com> wrote:
+1That observation actually would point to a different solution:
And,
4. Performance. The JVM can optimize static fields better than it can non-static fields when code is complex.
1) Make all fields and methods of top-level objects static
2) use name mangling if these static fields conflict with a companion class member (as they would otherwise be rejected by the verifier)
3) Add forwarders to static fields from the module object.
The advantage is that the Scala code generator does not need to dereference $MODULE fields
when accessing object members.
Another advantage is that @static would not be needed at all.
Cheers
-- Martin
--
Alois Cochardhttp://aloiscochard.blogspot.comhttp://twitter.com/aloiscochard
Tue, 2011-05-17, 16:07
#5
Re: Support @static annotation to create static fields or metho
On Tuesday, May 17, 2011 10:18:05 AM UTC-4, martin odersky wrote:
This isn't possible because top-level objects can extend classes/traits. They're objects, after all. Matter of fact, as a convenience, scalac spits out static helper methods into a class with the same name as the object, as long as it's not a companion of a trait -- which compiles to a Java interface and therefore cannot have static methods(*).
(* Subject to some interpretation. At the bytecode level, interfaces can have static _fields_ that can be initialized by bytecode compiled into the <clinit> method, which does in fact exist in the interface class file. I have never really tried wiring up a static method _with_ bytecode into an interface class file to see what it would do in the VM.)
As noted above, static forwarders exist, but they are methods. (In theory, vals could be fields, but scalac does not spit out non-private fields, ever.)
That observation actually would point to a different solution:
1) Make all fields and methods of top-level objects static
This isn't possible because top-level objects can extend classes/traits. They're objects, after all. Matter of fact, as a convenience, scalac spits out static helper methods into a class with the same name as the object, as long as it's not a companion of a trait -- which compiles to a Java interface and therefore cannot have static methods(*).
(* Subject to some interpretation. At the bytecode level, interfaces can have static _fields_ that can be initialized by bytecode compiled into the <clinit> method, which does in fact exist in the interface class file. I have never really tried wiring up a static method _with_ bytecode into an interface class file to see what it would do in the VM.)
3) Add forwarders to static fields from the module object.
As noted above, static forwarders exist, but they are methods. (In theory, vals could be fields, but scalac does not spit out non-private fields, ever.)
Tue, 2011-05-17, 16:17
#6
Re: Support @static annotation to create static fields or metho
martin odersky wrote:
BANLkTimgRqOeHnDBy0NzeCyin4y3JkyJjg [at] mail [dot] gmail [dot] com" type="cite">
On Tue, May 17, 2011 at 4:07 PM, Rex Kerr <ichoran [at] gmail [dot] com" rel="nofollow">ichoran@gmail.com> wrote:
+1That observation actually would point to a different solution:
And,
4. Performance. The JVM can optimize static fields better than it can non-static fields when code is complex.
1) Make all fields and methods of top-level objects static
2) use name mangling if these static fields conflict with a companion class member (as they would otherwise be rejected by the verifier)
3) Add forwarders to static fields from the module object.
The advantage is that the Scala code generator does not need to dereference $MODULE fields
when accessing object members.
Another advantage is that @static would not be needed at all.
I think it would still be required for reasons 1-3 that I've listed.
Ittay
BANLkTimgRqOeHnDBy0NzeCyin4y3JkyJjg [at] mail [dot] gmail [dot] com" type="cite">
Cheers
-- Martin
Tue, 2011-05-17, 16:27
#7
Re: Support @static annotation to create static fields or metho
Alois Cochard wrote:
BANLkTikaPAXowziJNdLnFNTWOUr_naUJUQ [at] mail [dot] gmail [dot] com" type="cite">
On 17 May 2011 15:00, Ittay Dror <ittay [dot] dror [at] gmail [dot] com" rel="nofollow">ittay.dror@gmail.com> wrote:
The common replyto such suggestions is "write this part in Java". But then it means I have to setup dual compilation of both Java and Scala in my module. Furthermore, the class that needs such a field may have non-trivial code, or maybe it needs to use other Scala classes which is sometimes tricky (e.g., you can't use the collection classes as-is in Java).
Don't see the problem you have with the 'write this part in Java' solution, if want to use Scala collections, why not use the Java class simply as a wrapper and call a Scala singleton when needed ?
It must not be that tricky if you use the Java class as a simple wrapper.
For example, I have this class:
class Service {
def foo(...): List[Int] = ....
}
Now I need to write a class that needs also a static method / field. And another method requires calling Service#foo. In Java, I can do very little with the result of foo. Obviously there are workarounds, such as having a fooForJava method that converts the list to a java list (via implicit conversion), but then the "just write this part in Java" becomes "just write this part in java and implement java compatible interfaces for all the end points that it requires"...
Ittay
BANLkTikaPAXowziJNdLnFNTWOUr_naUJUQ [at] mail [dot] gmail [dot] com" type="cite">
Regards,
Ittay
--
Alois Cochard http://aloiscochard.blogspot.com http://twitter.com/aloiscochard
Tue, 2011-05-17, 17:17
#8
Re: Support @static annotation to create static fields or method
On May 17, 3:18 pm, martin odersky wrote:
> > 4. Performance. The JVM can optimize static fields better than it can
> > non-static fields when code is complex.
>
> That observation actually would point to a different solution:
>
> 1) Make all fields and methods of top-level objects static
> 2) use name mangling if these static fields conflict with a companion class
> member (as they would otherwise be rejected by the verifier)
> 3) Add forwarders to static fields from the module object.
>
> The advantage is that the Scala code generator does not need to dereference
> $MODULE fields
> when accessing object members.
>
> Another advantage is that @static would not be needed at all.
+1 from me. I'm writing a computationally intentive app with "quite a
few" method calls a second, and no object allocations (after some
initialisation). I'm pretty sure that HotSpot is doing an impressive
amount of inlining already, but I did wonder whether I was starting to
hit against method dereferencing costs at this point (not sure how to
easily verify that though, it would be too much pain to rewrite in
Java).
Before somebody asks why I didn't just write it in Java in the first
place - I'm doing it for kicks, a realm where Java is excluded by
default. :)
Kieron
Tue, 2011-05-17, 17:27
#9
Re: Support @static annotation to create static fields or metho
On 5/17/11 6:00 AM, Ittay Dror wrote:
> I want to suggest that a new annotation @static will be added to core
> Scala. Methods or fields annotated with @static will be generated as
> static in bytecode.
For a topical example, to create yourkit probes I had to write a java
stub because of some combination of where the annotations ended up or
its expectations regarding things being static. (I didn't look that
closely since I was more interested in proceeding.)
// at least we can delegate most of it to scala
@MethodPattern("*:mapConserve(*)")
public class MyJavaProbe {
public static void onReturn(
final @This List target,
final @ReturnValue Object retval
) {
MapConserve.record(target, retval);
}
}
Tue, 2011-05-17, 18:47
#10
Re: Re: Support @static annotation to create static fields or m
You really should test before assuming one way or the other that you're being hit by method dereferencing. One place where it is relatively easy to detect a difference is in constants. So
object O {
val c = 1234
}
cannot be optimized the same way that
class O {
public static final int c = 1234
}
can be (at least with current Sun JVMs; of course, there's always a possibility for further improvement in the JIT compiler). However,
object O {
def c = 1234
}
*can* be optimized just like the Java code. Because of this, I now always write my constants in objects as defs, not vals. Rather counterintuitive, and I can't say I've tested every use case to make sure it's always superior or equal.
The other place I've "routinely" noticed a difference is in deep nestings like
object O {
def f(i: Int) = i*5
}
object P {
def f(i: Int) = O.f(i)
}
...
object T {
def f(i: Int) = S.f(i)
}
where at some point the JVM seems to give up on inlining. Since I've never taken the time to generate a synthetic benchmark that has shown this behavior (I've only discovered it in annoyingly complex code I've written), I am not sure that this is anything other than reducing the depth of nesting by one since the last thing is a field instead of a getter for a field. I am also not sure that the above example will show the behavior; it's something like this, but whether has to be a mixture of methods in classes and methods on objects and functions and such before the behavior appears, I can't currently say.
If the only reliable performance issue is the first one, the val-to-def translation is easy enough so it wouldn't motivate @static or any compiler magic to generate fields. If the second one could be verified as a reliable effect, and especially if it costs you more than one nesting level, then it would more strongly motivate some solution.
(And Ittay's original points are good ones regardless.)
--Rex
P.S. -optimise is of no help at all in the val c = 1234 vs. def c = 1234 matter.
On Tue, May 17, 2011 at 12:12 PM, Kieron Wilkinson <kieron.wilkinson@paretopartners.com> wrote:
object O {
val c = 1234
}
cannot be optimized the same way that
class O {
public static final int c = 1234
}
can be (at least with current Sun JVMs; of course, there's always a possibility for further improvement in the JIT compiler). However,
object O {
def c = 1234
}
*can* be optimized just like the Java code. Because of this, I now always write my constants in objects as defs, not vals. Rather counterintuitive, and I can't say I've tested every use case to make sure it's always superior or equal.
The other place I've "routinely" noticed a difference is in deep nestings like
object O {
def f(i: Int) = i*5
}
object P {
def f(i: Int) = O.f(i)
}
...
object T {
def f(i: Int) = S.f(i)
}
where at some point the JVM seems to give up on inlining. Since I've never taken the time to generate a synthetic benchmark that has shown this behavior (I've only discovered it in annoyingly complex code I've written), I am not sure that this is anything other than reducing the depth of nesting by one since the last thing is a field instead of a getter for a field. I am also not sure that the above example will show the behavior; it's something like this, but whether has to be a mixture of methods in classes and methods on objects and functions and such before the behavior appears, I can't currently say.
If the only reliable performance issue is the first one, the val-to-def translation is easy enough so it wouldn't motivate @static or any compiler magic to generate fields. If the second one could be verified as a reliable effect, and especially if it costs you more than one nesting level, then it would more strongly motivate some solution.
(And Ittay's original points are good ones regardless.)
--Rex
P.S. -optimise is of no help at all in the val c = 1234 vs. def c = 1234 matter.
On Tue, May 17, 2011 at 12:12 PM, Kieron Wilkinson <kieron.wilkinson@paretopartners.com> wrote:
On May 17, 3:18 pm, martin odersky <martin.oder...@epfl.ch> wrote:
> > 4. Performance. The JVM can optimize static fields better than it can
> > non-static fields when code is complex.
>
> That observation actually would point to a different solution:
>
> 1) Make all fields and methods of top-level objects static
> 2) use name mangling if these static fields conflict with a companion class
> member (as they would otherwise be rejected by the verifier)
> 3) Add forwarders to static fields from the module object.
>
> The advantage is that the Scala code generator does not need to dereference
> $MODULE fields
> when accessing object members.
>
> Another advantage is that @static would not be needed at all.
+1 from me. I'm writing a computationally intentive app with "quite a
few" method calls a second, and no object allocations (after some
initialisation). I'm pretty sure that HotSpot is doing an impressive
amount of inlining already, but I did wonder whether I was starting to
hit against method dereferencing costs at this point (not sure how to
easily verify that though, it would be too much pain to rewrite in
Java).
Before somebody asks why I didn't just write it in Java in the first
place - I'm doing it for kicks, a realm where Java is excluded by
default. :)
Kieron
Tue, 2011-05-17, 18:57
#11
Re: Support @static annotation to create static fields or metho
On 5/17/11 7:18 AM, martin odersky wrote:
> 1) Make all fields and methods of top-level objects static 2) use
> name mangling if these static fields conflict with a companion class
> member (as they would otherwise be rejected by the verifier) 3) Add
> forwarders to static fields from the module object.
This was proposed in a ticket (which sounded pretty plausible to me)
here, along with additional motivation to do so:
https://lampsvn.epfl.ch/trac/scala/ticket/3545
"object methods/fields at static scope should be implemented as static"
As an aside, I think too many good ideas disappear down the memory hole
this way. When someone has a good idea and articulates it at some
length, and we respond by shutting down the ticket and saying a SID is
required, the effect in practice in almost every case is that we will
have neither SID nor ticket. Nobody wants to lower the number of
outstanding tickets more than I do, but I don't think I should have to
maintain my fairly long list of "closed tickets I hope to rescue
someday" either.
As I see things watching the bug database spin further out of control
and knowing I will have less and less time to bail its water, we need
two more databases. One which is like trac but which only committers
can open tickets in, and one for ideas which exceed ticket scope but
have been vetted by some scala team member as worthy of further
investigation (i.e. "not completely out of the question.") This has
potential to improve out crowdsourcing.
> The advantage is that the Scala code generator does not need to
> dereference $MODULE fields when accessing object members.
>
> Another advantage is that @static would not be needed at all.
I think it's likely worth doing for performance alone, but I'm
skeptical it will actually remove the need to write java in most of the
places where this comes up. The problem is that the rest of the world
writes tools as if you will be writing in java so they assume you have
almost total control over bytecode layout. (Another example I've
personally enjoyed at some length is JNA, which requires public
fields.) Everywhere that we limit that control we potentially make
tools unusable from scala. Some of that cost is acceptable, some of it
is unavoidable, and some of it we should probably do something about.
Tue, 2011-05-17, 19:07
#12
Re: Re: Support @static annotation to create static fields or m
On Tue, May 17, 2011 at 6:42 PM, Rex Kerr wrote:
> So
> object O {
> val c = 1234
> }
> cannot be optimized the same way that
Try final val c = 1234 and check the bytecode. You'll see that the
value gets inlined:
3: sipush 1234
Ismael
Tue, 2011-05-17, 19:17
#13
Re: Support @static annotation to create static fields or metho
On 17 May 2011 18:06, "Paul Phillips" <paulp@improving.org> wrote:
>
> On 5/17/11 7:18 AM, martin odersky wrote:
> > 1) Make all fields and methods of top-level objects static 2) use
> > name mangling if these static fields conflict with a companion class
> > member (as they would otherwise be rejected by the verifier) 3) Add
> > forwarders to static fields from the module object.
>
> This was proposed in a ticket (which sounded pretty plausible to me)
> here, along with additional motivation to do so:
>
> https://lampsvn.epfl.ch/trac/scala/ticket/3545
> "object methods/fields at static scope should be implemented as static"
>
> As an aside, I think too many good ideas disappear down the memory hole
> this way. When someone has a good idea and articulates it at some
> length, and we respond by shutting down the ticket and saying a SID is
> required, the effect in practice in almost every case is that we will
> have neither SID nor ticket. Nobody wants to lower the number of
> outstanding tickets more than I do, but I don't think I should have to
> maintain my fairly long list of "closed tickets I hope to rescue
> someday" either.
>
> As I see things watching the bug database spin further out of control
> and knowing I will have less and less time to bail its water, we need
> two more databases. One which is like trac but which only committers
> can open tickets in, and one for ideas which exceed ticket scope but
> have been vetted by some scala team member as worthy of further
> investigation (i.e. "not completely out of the question.") This has
> potential to improve out crowdsourcing.
>
Has there ever been any consideration to an alternate tracking tool? As an open source project, I believe Scala would be eligible for a free Jira licence.
It would then be trivial to set up a workflow allowing "review for possible SID" as a resolution choice, and a second committer-only database.
> > The advantage is that the Scala code generator does not need to
> > dereference $MODULE fields when accessing object members.
> >
> > Another advantage is that @static would not be needed at all.
>
> I think it's likely worth doing for performance alone, but I'm
> skeptical it will actually remove the need to write java in most of the
> places where this comes up. The problem is that the rest of the world
> writes tools as if you will be writing in java so they assume you have
> almost total control over bytecode layout. (Another example I've
> personally enjoyed at some length is JNA, which requires public
> fields.) Everywhere that we limit that control we potentially make
> tools unusable from scala. Some of that cost is acceptable, some of it
> is unavoidable, and some of it we should probably do something about.
Tue, 2011-05-17, 19:27
#14
Re: Support @static annotation to create static fields or metho
On Tue, May 17, 2011 at 7:07 PM, Kevin Wright wrote:
> Has there ever been any consideration to an alternate tracking tool? As an
> open source project, I believe Scala would be eligible for a free Jira
> licence.
According to a tweet from Iulian, Scala will move to Jira and Git now
that 2.9.0 has been released.
Best,
Ismael
Tue, 2011-05-17, 19:37
#15
Re: Support @static annotation to create static fields or metho
On 17 May 2011 19:09, "Ismael Juma" <ismael@juma.me.uk> wrote:
>
> On Tue, May 17, 2011 at 7:07 PM, Kevin Wright <kev.lee.wright@gmail.com> wrote:
> > Has there ever been any consideration to an alternate tracking tool? As an
> > open source project, I believe Scala would be eligible for a free Jira
> > licence.
>
> According to a tweet from Iulian, Scala will move to Jira and Git now
> that 2.9.0 has been released.
>
Ah-hah!
Git, I remember. Must have read over the part about Jira.
Problem solved then. I'll even volunteer to help set up the workflows :)
> Best,
> Ismael
Tue, 2011-05-17, 19:47
#16
Re: Support @static annotation to create static fields or metho
It might be worth looking into getting a JIRA Studio instance.
Atlassian provides free instances to open source projects. It might
make sense since the compiler guys are already using Fisheye for
source repo browing and Crucible for code reviews. Studio has nice
integration setup between the apps that is otherwise a bit of a pain
to setup and maintain yourself (though we are working hard on that and
it is getting better!).
If there is interest, I can put you guys in touch with someone that
can make it happen.
Rich
On Tue, May 17, 2011 at 11:08 AM, Ismael Juma wrote:
> On Tue, May 17, 2011 at 7:07 PM, Kevin Wright wrote:
>> Has there ever been any consideration to an alternate tracking tool? As an
>> open source project, I believe Scala would be eligible for a free Jira
>> licence.
>
> According to a tweet from Iulian, Scala will move to Jira and Git now
> that 2.9.0 has been released.
>
> Best,
> Ismael
>
Tue, 2011-05-17, 20:07
#17
Re: Re: Support @static annotation to create static fields or m
Huh, right you are. Odd, given that "final val c" and "val c" have identical semantics inside objects.
--Rex
On Tue, May 17, 2011 at 1:52 PM, Ismael Juma <ismael@juma.me.uk> wrote:
--Rex
On Tue, May 17, 2011 at 1:52 PM, Ismael Juma <ismael@juma.me.uk> wrote:
On Tue, May 17, 2011 at 6:42 PM, Rex Kerr <ichoran@gmail.com> wrote:
> So
> object O {
> val c = 1234
> }
> cannot be optimized the same way that
Try final val c = 1234 and check the bytecode. You'll see that the
value gets inlined:
3: sipush 1234
Ismael
Tue, 2011-05-17, 20:17
#18
Re: Re: Support @static annotation to create static fields or m
Not quite identical:
scala> class A { val a = 4 }
defined class A
scala> class B extends A { override val a = 5 }
defined class B
scala> val f : A = new B
f: A = B@1494a05c
scala> f.a
res0: Int = 5
Non-final vals are dynamically dispatched.
Rex Kerr wrote:
scala> class A { val a = 4 }
defined class A
scala> class B extends A { override val a = 5 }
defined class B
scala> val f : A = new B
f: A = B@1494a05c
scala> f.a
res0: Int = 5
Non-final vals are dynamically dispatched.
Rex Kerr wrote:
BANLkTimbiV4k7pRbQAz1iXiL9fEC4BSwHg [at] mail [dot] gmail [dot] com" type="cite">Huh, right you are. Odd, given that "final val c" and "val c" have identical semantics inside objects.
--Rex
On Tue, May 17, 2011 at 1:52 PM, Ismael Juma <ismael [at] juma [dot] me [dot] uk" rel="nofollow">ismael@juma.me.uk> wrote:
On Tue, May 17, 2011 at 6:42 PM, Rex Kerr <ichoran [at] gmail [dot] com" rel="nofollow">ichoran@gmail.com> wrote:
> So
> object O {
> val c = 1234
> }
> cannot be optimized the same way that
Try final val c = 1234 and check the bytecode. You'll see that the
value gets inlined:
3: sipush 1234
Ismael
Tue, 2011-05-17, 20:27
#19
Re: Support @static annotation to create static fields or metho
On Tue, May 17, 2011 at 7:06 PM, Paul Phillips <paulp@improving.org> wrote:
On 5/17/11 7:18 AM, martin odersky wrote:
> 1) Make all fields and methods of top-level objects static 2) use
> name mangling if these static fields conflict with a companion class
> member (as they would otherwise be rejected by the verifier) 3) Add
> forwarders to static fields from the module object.
This was proposed in a ticket (which sounded pretty plausible to me)
here, along with additional motivation to do so:
https://lampsvn.epfl.ch/trac/scala/ticket/3545
"object methods/fields at static scope should be implemented as static"
As an aside, I think too many good ideas disappear down the memory hole
this way. When someone has a good idea and articulates it at some
length, and we respond by shutting down the ticket and saying a SID is
required, the effect in practice in almost every case is that we will
have neither SID nor ticket. Nobody wants to lower the number of
outstanding tickets more than I do, but I don't think I should have to
maintain my fairly long list of "closed tickets I hope to rescue
someday" either.
100% agree. We have recently created a new ticket assignee: future_release_suggestions. I just reassigned 3545 to that guy. Hopefully he will resolve it speedily ;-)
Cheers
-- Martin
Tue, 2011-05-17, 20:27
#20
Re: Re: Support @static annotation to create static fields or m
On Tue, May 17, 2011 at 3:16 PM, Bill Atkins wrote:
> Not quite identical:
>
> scala> class A { val a = 4 }
> defined class A
>
> scala> class B extends A { override val a = 5 }
> defined class B
However, you cannot extend a top-level object, yet:
object A {
val x = 1
final val y = 2
}
The bytecode for A.x() is:
0: aload_0
1: getfield #15; //Field x:I
4: ireturn
yet the bytecode for A.y() is:
0: iconst_2
1: ireturn
It seems that the inliner isn't always taking into account
_class_-finality when determining when inlining is possible. (Here,
the class A$, which is the type of the singleton A$.MODULE$, is final
Tue, 2011-05-17, 20:37
#21
Re: Re: Support @static annotation to create static fields or m
On Tue, May 17, 2011 at 9:02 PM, Rex Kerr wrote:
> Huh, right you are. Odd, given that "final val c" and "val c" have
> identical semantics inside objects.
It's described as a "constant value definition", in section 4.1 of the
spec. Note that if you add a type annotation, it's no longer inlined.
-jason
Tue, 2011-05-17, 20:47
#22
Re: Support @static annotation to create static fields or method
On May 17, 6:42 pm, Rex Kerr wrote:
> You really should test before assuming one way or the other that you're
> being hit by method dereferencing. One place where it is relatively easy to
Thanks for the comments Rex. No, I certainly didn't assume it was the
problem, and that was why I used the words "I did wonder whether" :)
You're right, I should test it, but that is not through any lack of
trying.
The problem I am coming up against, which you also mention, is
situations where the code is complicated. I have found it hard to
reduce the problem to a micro-benchmark that I could then compare with
plain Java. It's quite a bit of code...
I did think I had some reason to wonder whether my code is affected by
method dereferencing, purely because it has no object allocations,
just bit twiddling, a bit of array access, and tons of (nested, yes)
method calls. I have done a fair bit of profiling with YourKit, and
there is nothing in particular that stands out - the cost is pretty
evenly spread around many simple methods.
Since I gather that static calls are better optimised by the JVM, my
+1 was mainly motivated by being able to more easily test any
difference.
> P.S. -optimise is of no help at all in the val c = 1234 vs. def c = 1234
> matter.
Yeah, I tried that too and indeed it doesn't seem to have any
noticeable effect. I understand that -optimise is designed mainly for
inlining closure-like functions calls that the JVM isn't very good
inlining, so since I'm not doing that, it's not too surprising.
Kieron
Tue, 2011-05-17, 20:57
#23
Re: Re: Support @static annotation to create static fields or m
On 5/17/11 12:22 PM, Todd Vierling wrote:
> It seems that the inliner isn't always taking into account
> _class_-finality when determining when inlining is possible.
It isn't determining whether inlining is possible, it is determining
whether it is desired. Marking it as final is how you indicate the
latter. This is specified, though obscure.
> (Here, the class A$, which is the type of the singleton A$.MODULE$,
> is final -- but scalac isn't treating all members as final for the
> purpose of inlining.)
Yes, because the question is not whether it is effectively final, but
whether it has been explicitly marked with a final modifier.
Wed, 2011-05-18, 02:17
#24
Re: Support @static annotation to create static fields or metho
On 5/17/2011 9:18 AM, martin odersky wrote:
> On Tue, May 17, 2011 at 4:07 PM, Rex Kerr wrote:
>
>> +1
>>
>> And,
>>
>> 4. Performance. The JVM can optimize static fields better than it can
>> non-static fields when code is complex.
>>
>>
> That observation actually would point to a different solution:
>
> 1) Make all fields and methods of top-level objects static
> 2) use name mangling if these static fields conflict with a companion class
> member (as they would otherwise be rejected by the verifier)
> 3) Add forwarders to static fields from the module object.
>
> The advantage is that the Scala code generator does not need to dereference
> $MODULE fields
> when accessing object members.
>
> Another advantage is that @static would not be needed at all.
>
> Cheers
>
> -- Martin
>
Now, that's the way to do it. Java interoperability is good, but
language support is better. Also, fewer Java-specific tweaks are less
of a pain to the .Net guys. I've never used their stuff, but I do not
envy their task.
Bob
Thu, 2011-05-19, 04:17
#25
השב: Re: Support @static annotation to create static fields or
What is the status of this suggestion? Should I open an issue in Jira?
Ittay
בתאריך יום שלישי, 17 במאי 2011 18:06:07 UTC+3, מאת Ittay Dror:
Ittay
בתאריך יום שלישי, 17 במאי 2011 18:06:07 UTC+3, מאת Ittay Dror:
martin odersky wrote:
On Tue, May 17, 2011 at 4:07 PM, Rex Kerr <ich...@gmail.com> wrote:
+1That observation actually would point to a different solution:
And,
4. Performance. The JVM can optimize static fields better than it can non-static fields when code is complex.
1) Make all fields and methods of top-level objects static
2) use name mangling if these static fields conflict with a companion class member (as they would otherwise be rejected by the verifier)
3) Add forwarders to static fields from the module object.
The advantage is that the Scala code generator does not need to dereference $MODULE fields
when accessing object members.
Another advantage is that @static would not be needed at all.
I think it would still be required for reasons 1-3 that I've listed.
Ittay
Cheers
-- Martin
Thu, 2011-05-19, 07:27
#26
Re: השב: Re: Support @static annotation to create static fields
On Thu, May 19, 2011 at 5:14 AM, Ittay Dror <ittay.dror@gmail.com> wrote:
What is the status of this suggestion? Should I open an issue in Jira?I don't see why. I would have thought these points are addressed by my proposal. Can you explain?
Ittay
בתאריך יום שלישי, 17 במאי 2011 18:06:07 UTC+3, מאת Ittay Dror:
martin odersky wrote:
On Tue, May 17, 2011 at 4:07 PM, Rex Kerr <ich...@gmail.com> wrote:
+1That observation actually would point to a different solution:
And,
4. Performance. The JVM can optimize static fields better than it can non-static fields when code is complex.
1) Make all fields and methods of top-level objects static
2) use name mangling if these static fields conflict with a companion class member (as they would otherwise be rejected by the verifier)
3) Add forwarders to static fields from the module object.
The advantage is that the Scala code generator does not need to dereference $MODULE fields
when accessing object members.
Another advantage is that @static would not be needed at all.
I think it would still be required for reasons 1-3 that I've listed.
Best,
-- Martin
Thu, 2011-05-19, 09:27
#27
Re: השב: Re: Support @static annotation to create static fields
martin odersky wrote:
BANLkTimVXLCOwMPehxxPRJnMC+5reKTFfQ [at] mail [dot] gmail [dot] com" type="cite">
On Thu, May 19, 2011 at 5:14 AM, Ittay Dror <ittay [dot] dror [at] gmail [dot] com" rel="nofollow">ittay.dror@gmail.com> wrote:
What is the status of this suggestion? Should I open an issue in Jira?I don't see why. I would have thought these points are addressed by my proposal. Can you explain?
Ittay
בתאריך יום שלישי, 17 במאי 2011 18:06:07 UTC+3, מאת Ittay Dror:
martin odersky wrote:
On Tue, May 17, 2011 at 4:07 PM, Rex Kerr <ich...@gmail.com> wrote:
+1That observation actually would point to a different solution:
And,
4. Performance. The JVM can optimize static fields better than it can non-static fields when code is complex.
1) Make all fields and methods of top-level objects static
2) use name mangling if these static fields conflict with a companion class member (as they would otherwise be rejected by the verifier)
3) Add forwarders to static fields from the module object.
The advantage is that the Scala code generator does not need to dereference $MODULE fields
when accessing object members.
Another advantage is that @static would not be needed at all.
I think it would still be required for reasons 1-3 that I've listed.
If I understand your proposal, it means that something like:
object Foo {
def bar = "hi"
}
will be generated as:
class Foo {
static public String bar() {return "hi";}
}
right?
If so:
1. in android, a class implementing the Parcelable interface needs a static field. Here's an example from the android docs:
public class MyParcelable implements Parcelable { private int mData; public int describeContents() { return 0; } public void writeToParcel(Parcel out, int flags) { out.writeInt(mData); } public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() { public MyParcelable createFromParcel(Parcel in) { return new MyParcelable(in); } public MyParcelable[] newArray(int size) { return new MyParcelable[size]; } }; private MyParcelable(Parcel in) { mData = in.readInt(); } } This is a class with mixed methods and static methods. Paul mentioned another example when working with YourKit 2. If I create a Serializable class, I need to use the @SerialVersionUID: @SerialVersionUID(1234) class MyClass can be converted to class MyClass { @static private val serialVersionUID = 1234 }which is closer to Java and doesn't require knowing there exists a special annotation for this
3. the political argument is just so that if someone comes to me asking if scala can be used in environment X (JEE container, android, app-engine etc....), I can safely say: yes. (at least with regard to static. i'm sure there are more things you can do in java that you can't in scala).
Ittay
BANLkTimVXLCOwMPehxxPRJnMC+5reKTFfQ [at] mail [dot] gmail [dot] com" type="cite">
Best,
-- Martin
Thu, 2011-05-19, 13:07
#28
Re: השב: Re: Support @static annotation to create static fields
On Thu, May 19, 2011 at 10:23 AM, Ittay Dror <ittay.dror@gmail.com> wrote:
martin odersky wrote:
On Thu, May 19, 2011 at 5:14 AM, Ittay Dror <ittay.dror@gmail.com> wrote:
What is the status of this suggestion? Should I open an issue in Jira?I don't see why. I would have thought these points are addressed by my proposal. Can you explain?
Ittay
בתאריך יום שלישי, 17 במאי 2011 18:06:07 UTC+3, מאת Ittay Dror:
martin odersky wrote:
On Tue, May 17, 2011 at 4:07 PM, Rex Kerr <ich...@gmail.com> wrote:
+1That observation actually would point to a different solution:
And,
4. Performance. The JVM can optimize static fields better than it can non-static fields when code is complex.
1) Make all fields and methods of top-level objects static
2) use name mangling if these static fields conflict with a companion class member (as they would otherwise be rejected by the verifier)
3) Add forwarders to static fields from the module object.
The advantage is that the Scala code generator does not need to dereference $MODULE fields
when accessing object members.
Another advantage is that @static would not be needed at all.
I think it would still be required for reasons 1-3 that I've listed.
If I understand your proposal, it means that something like:
object Foo {
def bar = "hi"
}
will be generated as:
class Foo {
static public String bar() {return "hi";}
}
right?
Yes, but the same for fields. Object fields would become static fields of the class.
Thu, 2011-05-19, 13:37
#29
Re: השב: Re: Support @static annotation to create static fields
Ittay, I have a question. What's do you expect the visibility of this
to be? For instance, say you have:
class MyParcelable extends Parcelable {
@static private val mData: Int = _
def writeToParcel(out: Parcel , flags: Inf) {
out.writeInt(mData)
}
Do you expect that code to work? What about non-private members:
class Example {
@static val x = 0
}
Should Example.x be visible? Or would it only be visible through (new
Example).x?
The problem with introducing static scoping is that it introduces
static scoping. I'd really much prefer for it to be a Java-visible
side effect of a standard Scala feature.
On Thu, May 19, 2011 at 05:23, Ittay Dror wrote:
>
>
> martin odersky wrote:
>
>
> On Thu, May 19, 2011 at 5:14 AM, Ittay Dror wrote:
>>
>> What is the status of this suggestion? Should I open an issue in Jira?
>>
>> Ittay
>>
>> בתאריך יום שלישי, 17 במאי 2011 18:06:07 UTC+3, מאת Ittay Dror:
>>>
>>> martin odersky wrote:
>>>
>>>
>>> On Tue, May 17, 2011 at 4:07 PM, Rex Kerr wrote:
>>>>
>>>> +1
>>>>
>>>> And,
>>>>
>>>> 4. Performance. The JVM can optimize static fields better than it can
>>>> non-static fields when code is complex.
>>>>
>>>
>>> That observation actually would point to a different solution:
>>>
>>> 1) Make all fields and methods of top-level objects static
>>> 2) use name mangling if these static fields conflict with a companion
>>> class member (as they would otherwise be rejected by the verifier)
>>> 3) Add forwarders to static fields from the module object.
>>>
>>> The advantage is that the Scala code generator does not need to
>>> dereference $MODULE fields
>>> when accessing object members.
>>>
>>> Another advantage is that @static would not be needed at all.
>>>
>>> I think it would still be required for reasons 1-3 that I've listed.
>>>
> I don't see why. I would have thought these points are addressed by my
> proposal. Can you explain?
>
> If I understand your proposal, it means that something like:
> object Foo {
> def bar = "hi"
> }
>
> will be generated as:
> class Foo {
> static public String bar() {return "hi";}
> }
>
> right?
>
> If so:
>
> 1. in android, a class implementing the Parcelable interface needs a static
> field. Here's an example from the android docs:
>
> public class MyParcelable implements Parcelable {
> private int mData;
>
> public int describeContents() {
> return 0;
> }
>
> public void writeToParcel(Parcel out, int flags) {
> out.writeInt(mData);
> }
>
> public static final Parcelable.Creator CREATOR
> = new Parcelable.Creator() {
> public MyParcelable createFromParcel(Parcel in) {
> return new MyParcelable(in);
> }
>
> public MyParcelable[] newArray(int size) {
> return new MyParcelable[size];
> }
> };
>
> private MyParcelable(Parcel in) {
> mData = in.readInt();
> }
> }
>
> This is a class with mixed methods and static methods.
>
> Paul mentioned another example when working with YourKit
>
> 2. If I create a Serializable class, I need to use the @SerialVersionUID:
>
> @SerialVersionUID(1234)
> class MyClass
>
> can be converted to
>
> class MyClass {
> @static private val serialVersionUID = 1234
> }
>
> which is closer to Java and doesn't require knowing there exists a special
> annotation for this
>
> 3. the political argument is just so that if someone comes to me asking if
> scala can be used in environment X (JEE container, android, app-engine
> etc....), I can safely say: yes. (at least with regard to static. i'm sure
> there are more things you can do in java that you can't in scala).
>
> Ittay
>
>
>
> Best,
>
> -- Martin
>
>
Thu, 2011-05-19, 15:07
#30
Re: השב: Re: Support @static annotation to create static fields
On 5/19/11 4:59 AM, martin odersky wrote:
> Yes, but the same for fields. Object fields would become static fields
> of the class.
The general requirement in these situations, at least the ones I've
encountered, is a *public* static field.
Thu, 2011-05-19, 15:37
#31
Re: השב: Re: Support @static annotation to create static fields
On Thu, May 19, 2011 at 4:00 PM, Paul Phillips <paulp@improving.org> wrote:
On 5/19/11 4:59 AM, martin odersky wrote:
> Yes, but the same for fields. Object fields would become static fields
> of the class.
The general requirement in these situations, at least the ones I've
encountered, is a *public* static field.
OK, yes. That's a bit harder to engineer. -- Martin
Thu, 2011-05-19, 15:47
#32
Re: השב: Re: Support @static annotation to create static fields
On Thu, May 19, 2011 at 7:59 AM, martin odersky <martin.odersky@epfl.ch> wrote:> Yes, but the same for fields. Object fields would become static fields of> the class.
I can see the utility of this. Note that if fields are exposed, they need access modifiers (public by default, or private if specified) as many uses of field-based access require public fields.
Taking these into account, I see a possible implementation of the static _field_ idea as the following:
[optional class or trait] C { ...}
object C { @static val v = 0 @BeanProperty @static val b = 1 @static var s = 2 // compile error for a trait C: not immutable @static private val p = 3 // compile error for a trait C: not public var x = 4}
In the .class files, you would find:
===
C.class (for a class C or no C specified):- public static final int v- public static final int b- public static int s- private static int p- public static int v() // not an indirection, actual accessor code- public static int b() // not an indirection, actual accessor code- public static int getB() // not an indirection, actual accessor code- public static int s() // not an indirection, actual accessor code- public static void s_$eq(int) // not an indirection, actual accessor code- static int p() // can be Java "package private" as only C$ needs it- <clinit> { v = 0; b = 1; s = 2; p = 3 }
C$.class (for a class C or no C specified):- private int x- public int v() // indirection to static method- public int b() // indirection to static method- public int s() // indirection to static method- public void s_$eq(int) // indirection to static method- private int p() // indirection to static method- public int x()- public void x_$eq(int)- <init> { x = 4 }
===
C.class (for a trait C, with the compile error lines removed):- public static final int v- public static final int b- <clinit> { v = 0; b = 1 }
C$.class (for a trait C, with the compile error lines removed):- private int x- public int v() // not an indirection, actual accessor code- public int b() // not an indirection, actual accessor code- public int x()- public void x_$eq(int)- <init> { x = 4 }
I can see the utility of this. Note that if fields are exposed, they need access modifiers (public by default, or private if specified) as many uses of field-based access require public fields.
Taking these into account, I see a possible implementation of the static _field_ idea as the following:
[optional class or trait] C { ...}
object C { @static val v = 0 @BeanProperty @static val b = 1 @static var s = 2 // compile error for a trait C: not immutable @static private val p = 3 // compile error for a trait C: not public var x = 4}
In the .class files, you would find:
===
C.class (for a class C or no C specified):- public static final int v- public static final int b- public static int s- private static int p- public static int v() // not an indirection, actual accessor code- public static int b() // not an indirection, actual accessor code- public static int getB() // not an indirection, actual accessor code- public static int s() // not an indirection, actual accessor code- public static void s_$eq(int) // not an indirection, actual accessor code- static int p() // can be Java "package private" as only C$ needs it- <clinit> { v = 0; b = 1; s = 2; p = 3 }
C$.class (for a class C or no C specified):- private int x- public int v() // indirection to static method- public int b() // indirection to static method- public int s() // indirection to static method- public void s_$eq(int) // indirection to static method- private int p() // indirection to static method- public int x()- public void x_$eq(int)- <init> { x = 4 }
===
C.class (for a trait C, with the compile error lines removed):- public static final int v- public static final int b- <clinit> { v = 0; b = 1 }
C$.class (for a trait C, with the compile error lines removed):- private int x- public int v() // not an indirection, actual accessor code- public int b() // not an indirection, actual accessor code- public int x()- public void x_$eq(int)- <init> { x = 4 }
Thu, 2011-05-19, 15:57
#33
Re: השב: Re: Support @static annotation to create static fields
On Thu, May 19, 2011 at 3:31 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
Ittay, I have a question. What's do you expect the visibility of this
to be? For instance, say you have:
class MyParcelable extends Parcelable {
@static private val mData: Int = _
def writeToParcel(out: Parcel , flags: Inf) {
out.writeInt(mData)
}
Do you expect that code to work? What about non-private members:
i guess not, since then it opens a can of worms of NoOOP design.
but note this is not the use of @static for Parcelable. It is for the CREATOR field
My initial thought was something like:
class MyParcelable private(in: Parcel) extends Parcelable {
private val mdata = in.readInt
def describeContents = 0
def writeToParcel(out: Parcel, flags: Int) = out.writeInt(mData)
@static val CREATOR = new Parcelable[MyParcelable] {
def createFromParcel(in: Parcel) = new Parcelable(in)
def newArray(size: Int) = new Array[MyParcelable](size)
}
}
But I guess it is not very consistent with the rest of the language (unless it is not accessible from Scala code, like a @bridge method, which would be awkward)
So after thinking about it, I think I now understand Martin's suggestion better. It should be:
class MyParcelable private(in: Parcel) extends Parcelable {
private val mdata = in.readInt
def describeContents = 0
def writeToParcel(out: Parcel, flags: Int) = out.writeInt(mData)
}
object MyParcelable {
val CREATOR = new Parcelable[MyParcelable] {
def createFromParcel(in: Parcel) = new Parcelable(in)
def newArray(size: Int) = new Array[MyParcelable](size)
}
}
Which will create a private field and accessor methods, which is not what is required.
So, maybe change the suggestion to @field annotation?
object MyParcelable {
@field val CREATOR = new Parcelable[MyParcelable] {
def createFromParcel(in: Parcel) = new Parcelable(in)
def newArray(size: Int) = new Array[MyParcelable](size)
}
}
Will use Martin's suggestion, but create a field.
Then it should be accessible from Scala code in the same way a public field in a Java class will be accessible?
Ittay
class Example {
@static val x = 0
}
Should Example.x be visible? Or would it only be visible through (new
Example).x?
The problem with introducing static scoping is that it introduces
static scoping. I'd really much prefer for it to be a Java-visible
side effect of a standard Scala feature.
On Thu, May 19, 2011 at 05:23, Ittay Dror <ittay.dror@gmail.com> wrote:
>
>
> martin odersky wrote:
>
>
> On Thu, May 19, 2011 at 5:14 AM, Ittay Dror <ittay.dror@gmail.com> wrote:
>>
>> What is the status of this suggestion? Should I open an issue in Jira?
>>
>> Ittay
>>
>> בתאריך יום שלישי, 17 במאי 2011 18:06:07 UTC+3, מאת Ittay Dror:
>>>
>>> martin odersky wrote:
>>>
>>>
>>> On Tue, May 17, 2011 at 4:07 PM, Rex Kerr <ich...@gmail.com> wrote:
>>>>
>>>> +1
>>>>
>>>> And,
>>>>
>>>> 4. Performance. The JVM can optimize static fields better than it can
>>>> non-static fields when code is complex.
>>>>
>>>
>>> That observation actually would point to a different solution:
>>>
>>> 1) Make all fields and methods of top-level objects static
>>> 2) use name mangling if these static fields conflict with a companion
>>> class member (as they would otherwise be rejected by the verifier)
>>> 3) Add forwarders to static fields from the module object.
>>>
>>> The advantage is that the Scala code generator does not need to
>>> dereference $MODULE fields
>>> when accessing object members.
>>>
>>> Another advantage is that @static would not be needed at all.
>>>
>>> I think it would still be required for reasons 1-3 that I've listed.
>>>
> I don't see why. I would have thought these points are addressed by my
> proposal. Can you explain?
>
> If I understand your proposal, it means that something like:
> object Foo {
> def bar = "hi"
> }
>
> will be generated as:
> class Foo {
> static public String bar() {return "hi";}
> }
>
> right?
>
> If so:
>
> 1. in android, a class implementing the Parcelable interface needs a static
> field. Here's an example from the android docs:
>
> public class MyParcelable implements Parcelable {
> private int mData;
>
> public int describeContents() {
> return 0;
> }
>
> public void writeToParcel(Parcel out, int flags) {
> out.writeInt(mData);
> }
>
> public static final Parcelable.Creator<MyParcelable> CREATOR
> = new Parcelable.Creator<MyParcelable>() {
> public MyParcelable createFromParcel(Parcel in) {
> return new MyParcelable(in);
> }
>
> public MyParcelable[] newArray(int size) {
> return new MyParcelable[size];
> }
> };
>
> private MyParcelable(Parcel in) {
> mData = in.readInt();
> }
> }
>
> This is a class with mixed methods and static methods.
>
> Paul mentioned another example when working with YourKit
>
> 2. If I create a Serializable class, I need to use the @SerialVersionUID:
>
> @SerialVersionUID(1234)
> class MyClass
>
> can be converted to
>
> class MyClass {
> @static private val serialVersionUID = 1234
> }
>
> which is closer to Java and doesn't require knowing there exists a special
> annotation for this
>
> 3. the political argument is just so that if someone comes to me asking if
> scala can be used in environment X (JEE container, android, app-engine
> etc....), I can safely say: yes. (at least with regard to static. i'm sure
> there are more things you can do in java that you can't in scala).
>
> Ittay
>
>
>
> Best,
>
> -- Martin
>
>
--
Daniel C. Sobral
I travel to the future all the time.
Thu, 2011-05-19, 16:07
#34
Re: השב: Re: Support @static annotation to create static fields
I guess I'm more of the opinion that using Java to interface with Java libs can make sense. Android is, unfortunately, geared towards Java and its idioms... Why not leverage the beautiful Scala/Java integration and just make a class in Java that calls your Scala? Or subclass a Scala class?
On Thu, May 19, 2011 at 10:41 AM, Todd Vierling <tv@duh.org> wrote:
On Thu, May 19, 2011 at 10:41 AM, Todd Vierling <tv@duh.org> wrote:
On Thu, May 19, 2011 at 7:59 AM, martin odersky <martin.odersky@epfl.ch> wrote:> Yes, but the same for fields. Object fields would become static fields of > the class.
I can see the utility of this. Note that if fields are exposed, they need access modifiers (public by default, or private if specified) as many uses of field-based access require public fields.
Taking these into account, I see a possible implementation of the static _field_ idea as the following:
[optional class or trait] C { ...}
object C { @static val v = 0 @BeanProperty @static val b = 1 @static var s = 2 // compile error for a trait C: not immutable @static private val p = 3 // compile error for a trait C: not public var x = 4}
In the .class files, you would find:
===
C.class (for a class C or no C specified):- public static final int v - public static final int b- public static int s- private static int p- public static int v() // not an indirection, actual accessor code- public static int b() // not an indirection, actual accessor code - public static int getB() // not an indirection, actual accessor code- public static int s() // not an indirection, actual accessor code- public static void s_$eq(int) // not an indirection, actual accessor code - static int p() // can be Java "package private" as only C$ needs it- <clinit> { v = 0; b = 1; s = 2; p = 3 }
C$.class (for a class C or no C specified): - private int x- public int v() // indirection to static method- public int b() // indirection to static method- public int s() // indirection to static method- public void s_$eq(int) // indirection to static method - private int p() // indirection to static method- public int x()- public void x_$eq(int)- <init> { x = 4 }
===
C.class (for a trait C, with the compile error lines removed): - public static final int v- public static final int b- <clinit> { v = 0; b = 1 }
C$.class (for a trait C, with the compile error lines removed):- private int x - public int v() // not an indirection, actual accessor code- public int b() // not an indirection, actual accessor code- public int x()- public void x_$eq(int)- <init> { x = 4 }
Thu, 2011-05-19, 16:17
#35
Re: השב: Re: Support @static annotation to create static fields
On Thursday, May 19, 2011 10:41:01 AM UTC-4, Todd Vierling wrote:
A very tricky part of this is ordering of members. Since the code to initialize static final fields in a class or interface must reside in that .class's <clinit> method, out-of-order evaluation can cause headaches. I would propose that all @static fields be required to be at the top of the object, before any other var or val declaration. So the following would not be legal:
object O { val x = List(1, 2, 3) @static val y = ... // compile error: init code exists before this
// // In theory, a _constant literal_ could be declared @static here, // but that way might lie confusion.}
but the following could be legal. Note where bytecode would go depending on where it happens:
object O extends Foo { // // bytecode compiles to O.<clinit> first, and superclass/trait initialization hasn't happened yet... // @static val x = List(1, 2, 3) x.foreach(println(_)) @static val y = x.map(_.asInstanceOf[Double]) // // ...then bytecode switches to O$.<init> here, and Foo.<init> is *now* called before the bytecode continues. // val z = x.map(_.asInstanceOf[Float])}
Another side-effect of this is that @static members cannot access any members of superclasses or inherited traits, since they will not yet be initialized.
Taking these into account, I see a possible implementation of the static _field_ idea as the following:
A very tricky part of this is ordering of members. Since the code to initialize static final fields in a class or interface must reside in that .class's <clinit> method, out-of-order evaluation can cause headaches. I would propose that all @static fields be required to be at the top of the object, before any other var or val declaration. So the following would not be legal:
object O { val x = List(1, 2, 3) @static val y = ... // compile error: init code exists before this
// // In theory, a _constant literal_ could be declared @static here, // but that way might lie confusion.}
but the following could be legal. Note where bytecode would go depending on where it happens:
object O extends Foo { // // bytecode compiles to O.<clinit> first, and superclass/trait initialization hasn't happened yet... // @static val x = List(1, 2, 3) x.foreach(println(_)) @static val y = x.map(_.asInstanceOf[Double]) // // ...then bytecode switches to O$.<init> here, and Foo.<init> is *now* called before the bytecode continues. // val z = x.map(_.asInstanceOf[Float])}
Another side-effect of this is that @static members cannot access any members of superclasses or inherited traits, since they will not yet be initialized.
Thu, 2011-05-19, 16:47
#36
Re: השב: Re: Support @static annotation to create static fields
Josh Suereth wrote:
BANLkTikwwTPPtG+MiFdVSi8BnpamELE1Ow [at] mail [dot] gmail [dot] com" type="cite">I guess I'm more of the opinion that using Java to interface with Java libs can make sense. Android is, unfortunately, geared towards Java and its idioms... Why not leverage the beautiful Scala/Java integration and just make a class in Java that calls your Scala? Or subclass a Scala class?
I guess when achieving a high level of confidence that Scala is *the* language, one can argue that Java is to Scala like C is to Java: sometimes you need it for the icky parts....
I for one would not give up Scala for such instances as I've described.
However, I think that in the mindset of many people, Scala is still not there. It has to prove itself as equivalent and better than Java. And these corner cases just make it look inferior to those "unenlightened".
Android development is inferior as-is in Scala, compared to the Eclipse plugin. Telling a developer he needs to go to pains of understanding SBT and then compiling in the console, so as to work with Scala, and then having to still use Java for some parts requires a better selling skills than what I have. And I want to sell Scala! (Btw, not sure the status now, but there used to be issues with EJB)
So I'm trying to suggest ways, which I hope are easy to implement, which would close these holes. Obviously, if they break the language model , or are too complex to implement, then they are not worth it, but it also means less niches where Scala can inch its way towards JVM domination.
Ittay
BANLkTikwwTPPtG+MiFdVSi8BnpamELE1Ow [at] mail [dot] gmail [dot] com" type="cite">
On Thu, May 19, 2011 at 10:41 AM, Todd Vierling <tv [at] duh [dot] org" rel="nofollow">tv@duh.org> wrote:
On Thu, May 19, 2011 at 7:59 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch" target="_blank" rel="nofollow">martin.odersky@epfl.ch> wrote: > Yes, but the same for fields. Object fields would become static fields of > the class.
I can see the utility of this. Note that if fields are exposed, they need access modifiers (public by default, or private if specified) as many uses of field-based access require public fields.
Taking these into account, I see a possible implementation of the static _field_ idea as the following:
[optional class or trait] C { ... }
object C { @static val v = 0 @BeanProperty @static val b = 1 @static var s = 2 // compile error for a trait C: not immutable @static private val p = 3 // compile error for a trait C: not public var x = 4 }
In the .class files, you would find:
===
C.class (for a class C or no C specified): - public static final int v - public static final int b - public static int s - private static int p - public static int v() // not an indirection, actual accessor code - public static int b() // not an indirection, actual accessor code - public static int getB() // not an indirection, actual accessor code - public static int s() // not an indirection, actual accessor code - public static void s_$eq(int) // not an indirection, actual accessor code - static int p() // can be Java "package private" as only C$ needs it - <clinit> { v = 0; b = 1; s = 2; p = 3 }
C$.class (for a class C or no C specified): - private int x - public int v() // indirection to static method - public int b() // indirection to static method - public int s() // indirection to static method - public void s_$eq(int) // indirection to static method - private int p() // indirection to static method - public int x() - public void x_$eq(int) - <init> { x = 4 }
===
C.class (for a trait C, with the compile error lines removed): - public static final int v - public static final int b - <clinit> { v = 0; b = 1 }
C$.class (for a trait C, with the compile error lines removed): - private int x - public int v() // not an indirection, actual accessor code - public int b() // not an indirection, actual accessor code - public int x() - public void x_$eq(int) - <init> { x = 4 }
Fri, 2011-05-20, 19:37
#37
השב: Re: השב: Re: Support @static annotation to create static f
So, should I reopen the ticket on this, or is it a lost cause?
What about having @field annotation that will generate a field for a var/val instead of accessor methods?
Regards,
Ittay
What about having @field annotation that will generate a field for a var/val instead of accessor methods?
Regards,
Ittay
Sun, 2011-06-19, 12:57
#38
השב: Re: השב: Re: Support @static annotation to create static f
Another use case is of logging. In Java, creating a logger via:
private static finall Logger log = LoggerFactory.getLogger(MyClass.class)
In Scala, one can think of creating a trait Logging. However the log field in the trait will be created for each instance. This means an overhead both in memory and performance.
There are usually 2 replies to this issue: One is: "don't worry about it", the second is "you can create a companion object that extends Logging". I don't like both. The first just ignores the issue and the second means writing more code than in Java's case (create the companion, then prefix it each time a log is issued).
Ittay
private static finall Logger log = LoggerFactory.getLogger(MyClass.class)
In Scala, one can think of creating a trait Logging. However the log field in the trait will be created for each instance. This means an overhead both in memory and performance.
There are usually 2 replies to this issue: One is: "don't worry about it", the second is "you can create a companion object that extends Logging". I don't like both. The first just ignores the issue and the second means writing more code than in Java's case (create the companion, then prefix it each time a log is issued).
Ittay
Sun, 2011-06-19, 13:07
#39
השב: Support @static annotation to create static fields or metho
As for point 1: There's already a patch (or hack) in the compiler to deal with this (https://lampsvn.epfl.ch/trac/scala/changeset/22628). Unfortunately, it only handles this particular case. If the case was deemed worthy enough to create a compiler patch, why not do it in a generic way?
Ittay
Ittay
Sun, 2011-06-19, 13:17
#40
Re: השב: Re: השב: Re: Support @static annotation to create stat
On 19 June 2011 12:52, Ittay Dror <ittay.dror@gmail.com> wrote:
Another use case is of logging. In Java, creating a logger via:
private static finall Logger log = LoggerFactory.getLogger(MyClass.class)
In Scala, one can think of creating a trait Logging. However the log field in the trait will be created for each instance. This means an overhead both in memory and performance.
There are usually 2 replies to this issue: One is: "don't worry about it", the second is "you can create a companion object that extends Logging". I don't like both. The first just ignores the issue and the second means writing more code than in Java's case (create the companion, then prefix it each time a log is issued).
Seriously... don't worry about it!You're not creating a whole new logger with each object you create of some given class, just adding another reference to an existing logger instance.
The performance and memory cost is so small that even the most pedantic of micro-optimisation fans would struggle to find much benefit here.
Ittay
--
Kevin Wright
gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda
"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
Sun, 2011-06-19, 17:27
#41
Re: השב: Re: השב: Re: Support @static annotation to create stat
On Sun, Jun 19, 2011 at 1:03 PM, Kevin Wright <kev.lee.wright@gmail.com> wrote:
That's not true at all. There are many situations where an additional reference per object is a big deal. Not the common case though.
Best,Ismael
Seriously... don't worry about it!You're not creating a whole new logger with each object you create of some given class, just adding another reference to an existing logger instance.
The performance and memory cost is so small that even the most pedantic of micro-optimisation fans would struggle to find much benefit here.
That's not true at all. There are many situations where an additional reference per object is a big deal. Not the common case though.
Best,Ismael
Mon, 2011-06-20, 03:57
#42
Re: השב: Re: השב: Re: Support @static annotation to create stat
This doesn't fit the bill?
object Logger { def log(fmt:String,args:Any*) { if (args.isEmpty) println(fmt) else println(fmt.format(args :_*)) } def withLog[T](fmt:String,args:Any*)(body: => T):T = { log(fmt,args :_*) body } }
class Foo { import Logger._ def doSomethingWithLogging(x:Int):Int = { log("starting with:%s",x) withLog("incrementing") { x + 1 } } }
object Test { def test { val f = new Foo val x = f.doSomethingWithLogging(10) println(x) }}
Substitute your favorite logging stuff for the logger above. Pretty much all the logging libraries out there take care of multi-threaded access to the logger.
I presume that there is some subtlety I'm missing.
--
Jim Powers
object Logger { def log(fmt:String,args:Any*) { if (args.isEmpty) println(fmt) else println(fmt.format(args :_*)) } def withLog[T](fmt:String,args:Any*)(body: => T):T = { log(fmt,args :_*) body } }
class Foo { import Logger._ def doSomethingWithLogging(x:Int):Int = { log("starting with:%s",x) withLog("incrementing") { x + 1 } } }
object Test { def test { val f = new Foo val x = f.doSomethingWithLogging(10) println(x) }}
Substitute your favorite logging stuff for the logger above. Pretty much all the logging libraries out there take care of multi-threaded access to the logger.
I presume that there is some subtlety I'm missing.
--
Jim Powers
Mon, 2011-06-20, 04:47
#43
Re: השב: Re: השב: Re: Support @static annotation to create stat
Jim Powers wrote:
BANLkTikm7g0UK4BNX7K8muphoZwsapz+gQ [at] mail [dot] gmail [dot] com" type="cite">This doesn't fit the bill?
object Logger { def log(fmt:String,args:Any*) { if (args.isEmpty) println(fmt) else println(fmt.format(args :_*)) } def withLog[T](fmt:String,args:Any*)(body: => T):T = { log(fmt,args :_*) body } }
class Foo { import Logger._ def doSomethingWithLogging(x:Int):Int = { log("starting with:%s",x) withLog("incrementing") { x + 1 } } }
object Test { def test { val f = new Foo val x = f.doSomethingWithLogging(10) println(x) } }
Substitute your favorite logging stuff for the logger above. Pretty much all the logging libraries out there take care of multi-threaded access to the logger.
I presume that there is some subtlety I'm missing.
Most (all?) logging libraries allow to have separate loggers that can be controlled via a central configuration (set threshold, route to files etc.). So each class needs its own logger instance. For performance reasons, it's not good to have `log` that fetches/creates the logger, it needs to be a field somewhere.
Ittay
BANLkTikm7g0UK4BNX7K8muphoZwsapz+gQ [at] mail [dot] gmail [dot] com" type="cite">
--
Jim Powers
Mon, 2011-06-20, 14:27
#44
Re: השב: Re: השב: Re: Support @static annotation to create stat
Ahh, yeah, sure. I was simply addressing the extra field member issue someone was concerned about. I just use a logging mixin myself.
--
Jim Powers
>
>
> Jim Powers wrote:
>
>> This doesn't fit the bill?
>>
>> object Logger {
>> def log(fmt:String,args:Any*) {
>> if (args.isEmpty)
>> println(fmt)
>> else
>> println(fmt.format(args :_*))
>> }
>> def withLog[T](fmt:String,args:Any*)(body: => T):T = {
>> log(fmt,args :_*)
>> body
>> }
>> }
>>
>> class Foo {
>> import Logger._
>> def doSomethingWithLogging(x:Int):Int = {
>> log("starting with:%s",x)
>> withLog("incrementing") {
>> x + 1
>> }
>> }
>> }
>>
>> object Test {
>> def test {
>> val f = new Foo
>> val x = f.doSomethingWithLogging(10)
>> println(x)
>> }
>> }
>>
>> Substitute your favorite logging stuff for the logger above. Pretty
>> much all the logging libraries out there take care of multi-threaded
>> access to the logger.
>>
>> I presume that there is some subtlety I'm missing.
>
> Most (all?) logging libraries allow to have separate loggers that can be
> controlled via a central configuration (set threshold, route to files
> etc.). So each class needs its own logger instance. For performance
> reasons, it's not good to have `log` that fetches/creates the logger, it
> needs to be a field somewhere.
>
> Ittay
>
>
>>
>> --
>> Jim Powers
>>
And,
4. Performance. The JVM can optimize static fields better than it can non-static fields when code is complex.
--Rex
On Tue, May 17, 2011 at 9:00 AM, Ittay Dror <ittay.dror@gmail.com> wrote: