Will @static ship with 2.11?

256 views
Skip to first unread message

Simon Ochsenreither

unread,
Jan 25, 2013, 11:34:07 AM1/25/13
to scala-i...@googlegroups.com
Hi,

there were plans to include the @static annotation in 2.10 which sadly didn't work out that time.
Is there a chance to get it included in 2.11?

I'm interested in it, because imho it would be the cleanest way to implement the last blocking issue towards enums.
Moving/changing stuff around in the compiler would also be possible, but I really want to keep the enum implementation purely library-based and @static would enable that in a very sane way.

What's the current state/the repo with the latest changes of @static? I have looked in Aleksandar's repo, but I only found the addition of the class definition there.

Thanks and bye,

Simon

Adriaan Moors

unread,
Jan 28, 2013, 12:48:54 AM1/28/13
to scala-i...@googlegroups.com
if ( SIP(it) && implement(it) && test(it) && benchmark(it) ) true // in time...
else false

I don't know of anyone committed to making this true at this point.



--
 
 

Simon Ochsenreither

unread,
Jan 28, 2013, 5:52:15 PM1/28/13
to scala-i...@googlegroups.com
Do you know where the latest version currently is? I would have at least a look at it to see how hard it would be to resurrect, update it for the current version and figure out which issues remain.
Being stuck without @static is pretty annoying because it seems to be the cleanest way to emit static members, which is what currently bocks my work on enums.

Adriaan Moors

unread,
Jan 28, 2013, 6:37:55 PM1/28/13
to scala-i...@googlegroups.com
I think we've come to the conclusion that the old approach is doomed because of initialization issues.

The alternative approach suggested by Martin (IIRC) is to generate the implementation for methods in a @static companion object
in the static methods of the companion object's class, with forwarders defined in the module class (the one suffixed with $)

object O { def foo = ??? }

becomes

class O { public static void foo() { ??? } }
class O$ { public void foo() { return MODULE$.foo() }; public static final O$ MODULE$ = this; }

the issues with this:
  - need accessors to access protected methods in O's super classes
  - name clashes between static and non-static methods


On Mon, Jan 28, 2013 at 2:52 PM, Simon Ochsenreither <simon.och...@gmail.com> wrote:
Do you know where the latest version currently is? I would have at least a look at it to see how hard it would be to resurrect, update it for the current version and figure out which issues remain.
Being stuck without @static is pretty annoying because it seems to be the cleanest way to emit static members, which is what currently bocks my work on enums.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group, send email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Simon Ochsenreither

unread,
Jan 28, 2013, 8:21:31 PM1/28/13
to scala-i...@googlegroups.com
Hi Adriaan,


I think we've come to the conclusion that the old approach is doomed because of initialization issues.

Is there more info on that? I can't think in which ways they would suffer more from initialization issues than the rest of the language. Anyway, @static would be a tool of “you really need to know what you're doing” and not some “use it, it's fun” thing. I could live with an implementation which says “if you want to mess with static, don't complain about the consequences”.

Thanks and bye,

Simon

Grzegorz Kossakowski

unread,
Jan 28, 2013, 8:25:45 PM1/28/13
to scala-i...@googlegroups.com

--
Grzegorz Kossakowski
Scalac hacker at Typesafe
twitter: @gkossakowski

Simon Ochsenreither

unread,
Jan 28, 2013, 10:14:21 PM1/28/13
to scala-i...@googlegroups.com
Hi Grzegorz, hi Adriaan!


We care a lot about user experience and we do not indent to ship features that make it easy to shoot yourself in foot.

Well, it wouldn't have been exposed to users anyway? (It would have been something like scala[private], or am I mistaken?)

But I agree that it doesn't seem to be in an usable state right now.

So what options remain for the enum use-case https://docs.google.com/document/d/1mIKml4sJzezL_-iDJMmcAKmavHb9axjYJos_7UMlWJ8/edit#heading=h.duxj33qyodsd (DRAFT)?
I don't think that adding yet another special case for emitting static members in the compiler is a workable approach. :-/

Thanks and bye,

Simon

Grzegorz Kossakowski

unread,
Jan 29, 2013, 12:04:31 AM1/29/13
to scala-i...@googlegroups.com
On 28 January 2013 19:14, Simon Ochsenreither <simon.och...@gmail.com> wrote:
Hi Grzegorz, hi Adriaan!


We care a lot about user experience and we do not indent to ship features that make it easy to shoot yourself in foot.

Well, it wouldn't have been exposed to users anyway? (It would have been something like scala[private], or am I mistaken?)

Not sure if I follow. I meant that we don't want to ship any features which make problems with initialization worse than now. The @static as was considered a few months ago was making the situation a lot worse and that's why it got dropped in the end.
 

But I agree that it doesn't seem to be in an usable state right now.

So what options remain for the enum use-case https://docs.google.com/document/d/1mIKml4sJzezL_-iDJMmcAKmavHb9axjYJos_7UMlWJ8/edit#heading=h.duxj33qyodsd (DRAFT)?
I don't think that adding yet another special case for emitting static members in the compiler is a workable approach. :-/

The problem is tricky to be solved in general. May you elaborate why do you need statics in the first place? Why fields in companion object are not good enough?

Simon Ochsenreither

unread,
Jan 29, 2013, 12:25:36 AM1/29/13
to scala-i...@googlegroups.com
The @static as was considered a few months ago was making the situation a lot worse and that's why it got dropped in the end.

As far as I have seen now, it wouldn't have worked anyway because the annotation would have been restricted to objects and disallowed in classes.


The problem is tricky to be solved in general. May you elaborate why do you need statics in the first place? Why fields in companion object are not good enough?

The rules are made by the JDK, just like the static hack in scalac for Parceable is required by Android. It just won't work if the implementation doesn't follow the rules.

And I can't emit a companion object with macros anyway, otherwise I would have tried it and hoped that the static forwarders would be enough.

Thanks and bye,

Simon

Grzegorz Kossakowski

unread,
Jan 29, 2013, 12:30:09 AM1/29/13
to scala-i...@googlegroups.com
On 28 January 2013 21:25, Simon Ochsenreither <simon.och...@gmail.com> wrote:
The @static as was considered a few months ago was making the situation a lot worse and that's why it got dropped in the end.

As far as I have seen now, it wouldn't have worked anyway because the annotation would have been restricted to objects and disallowed in classes.

That's correct.
 
The problem is tricky to be solved in general. May you elaborate why do you need statics in the first place? Why fields in companion object are not good enough?

The rules are made by the JDK, just like the static hack in scalac for Parceable is required by Android. It just won't work if the implementation doesn't follow the rules.

Ok.
 
And I can't emit a companion object with macros anyway, otherwise I would have tried it and hoped that the static forwarders would be enough.

I see. I think exploring that space (macros) is better idea because it should be easier to fix it there. Scalac doesn't really have concept of static and I expect a lot of problems (really difficult ones) if you try to introduce it.

Simon Ochsenreither

unread,
Jan 29, 2013, 1:36:06 AM1/29/13
to scala-i...@googlegroups.com

 I see. I think exploring that space (macros) is better idea because it should be easier to fix it there. Scalac doesn't really have concept of static and I expect a lot of problems (really difficult ones) if you try to introduce it.

Sadly that's what I tried for days before I asked about resurrecting @static. I think my options concerning macros are currently pretty exhausted.
The issue is that even if I build the right tree, cast the symbol to the compiler's internal type and set the STATIC flag manually, the compiler ignores it and emits non-static members.

Aleksandar Prokopec

unread,
Jan 29, 2013, 8:47:10 AM1/29/13
to scala-i...@googlegroups.com, Adriaan Moors
On 1/29/13 12:37 AM, Adriaan Moors wrote:
I think we've come to the conclusion that the old approach is doomed because of initialization issues.


Would initialization issues still be a problem if the @static annotations was placed on members of the companion class instead of on the members of a companion object?
I.e., this:

class Foo {
  @static var bar = 1
}

instead of:

class Foo

object Foo {
  @static var bar = 1
}

Seems to me that it's much easier to reason about initialization of these fields then, since these the class Foo and its companion object Foo appear as separate entities.



The alternative approach suggested by Martin (IIRC) is to generate the implementation for methods in a @static companion object
in the static methods of the companion object's class, with forwarders defined in the module class (the one suffixed with $)

object O { def foo = ??? }

becomes

class O { public static void foo() { ??? } }
class O$ { public void foo() { return MODULE$.foo() }; public static final O$ MODULE$ = this; }


Can't remember the details right now, but I think the previous implementation worked this way.
Plus, calls to O$.MODULE$.foo() were replaced by calls to O.foo().


the issues with this:
  - need accessors to access protected methods in O's super classes
  - name clashes between static and non-static methods


On Mon, Jan 28, 2013 at 2:52 PM, Simon Ochsenreither <simon.och...@gmail.com> wrote:
Do you know where the latest version currently is? I would have at least a look at it to see how hard it would be to resurrect, update it for the current version and figure out which issues remain.
Being stuck without @static is pretty annoying because it seems to be the cleanest way to emit static members, which is what currently bocks my work on enums.
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group, send email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group, send email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 


-- 
Aleksandar Prokopec,
Doctoral Assistant
LAMP, IC, EPFL
http://people.epfl.ch/aleksandar.prokopec

Josh Suereth

unread,
Jan 29, 2013, 8:58:26 AM1/29/13
to scala-internals, Adriaan Moors
I think the issue there would be *enforcing* visibility and lifecycle of @static annotated things.   It's a far more aggressive change, possible the right way to support @static, but it seems to add a lot of complication in general.


To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.

Simon Ochsenreither

unread,
Jan 29, 2013, 12:44:20 PM1/29/13
to scala-i...@googlegroups.com, Adriaan Moors, aleksanda...@epfl.ch
Would initialization issues still be a problem if the @static annotations was placed on members of the companion class instead of on the members of a companion object?
Seems to me that it's much easier to reason about initialization of these fields then, since these the class Foo and its companion object Foo appear as separate entities.

And it would do pretty much everything needed fur the enum use-case. :-)

Roland Kuhn

unread,
Jan 29, 2013, 12:53:22 PM1/29/13
to scala-i...@googlegroups.com, Adriaan Moors
29 jan 2013 kl. 14:47 skrev Aleksandar Prokopec:

On 1/29/13 12:37 AM, Adriaan Moors wrote:
I think we've come to the conclusion that the old approach is doomed because of initialization issues.


Would initialization issues still be a problem if the @static annotations was placed on members of the companion class instead of on the members of a companion object?
I.e., this:

class Foo {
  @static var bar = 1
}

That is actually worse than putting it into the object, because instead of being intermingled with the MODULE constructor (which is run by the static initializer) it is now intermingled with the class’ normal constructor, which is not related at all. How do you explain to users that “this” is not available in certain statements?

Regards,

Roland

To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn

Simon Ochsenreither

unread,
Jan 29, 2013, 1:09:02 PM1/29/13
to scala-i...@googlegroups.com, Adriaan Moors

That is actually worse than putting it into the object, because instead of being intermingled with the MODULE constructor (which is run by the static initializer) it is now intermingled with the class’ normal constructor, which is not related at all.
I'm not sure this is the case. @static stuff should be initialized when the class is first referenced, that's the job of the static initializer of the class. Where would the class constructor get involved?
 
How do you explain to users that “this” is not available in certain statements?
I would propose something along the lines of “if it is static, this is not available”.


Rex Kerr

unread,
Jan 29, 2013, 1:16:09 PM1/29/13
to scala-i...@googlegroups.com, Adriaan Moors
What about putting it in a package?  You can have companion objects; why not companion packages?

class X {
  val x: Int = 7
}
object X {
  val y: Int = 8
}
package X {
  def z: Int = 9
}

Under the hood, package X would add a static method z to X, and a forwarder method to object X.  Seems like this would maintain consistent behavior and avoid all the initialization problems.

  --Rex

Roland Kuhn

unread,
Jan 29, 2013, 1:16:15 PM1/29/13
to scala-i...@googlegroups.com, Adriaan Moors
29 jan 2013 kl. 19:09 skrev Simon Ochsenreither:


That is actually worse than putting it into the object, because instead of being intermingled with the MODULE constructor (which is run by the static initializer) it is now intermingled with the class’ normal constructor, which is not related at all.
I'm not sure this is the case. @static stuff should be initialized when the class is first referenced, that's the job of the static initializer of the class. Where would the class constructor get involved?

The class template’s body is its constructor (apart from the field and method definitions). Putting @static code into this lexical context would be very wrong.

I’m still convinced that the @static fields should be initialized within the MODULE constructor, that has the right semantics in the right lexical context. One thing I’m not sure about is if it would be possible to support private and/or final static fields this way (depending on how picky the JVM is wrt. having a method which writes to a final field and which is not the constructor).

Regards,

Roland

 
How do you explain to users that “this” is not available in certain statements?
I would propose something along the lines of “if it is static, this is not available”.



--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Roland Kuhn

unread,
Jan 29, 2013, 1:19:32 PM1/29/13
to scala-i...@googlegroups.com, Adriaan Moors
This sounds really good! If it is grammatically possible (i.e. no namespace problems) then I think this would solve all problems. Especially since packages are not values, hence do not need to be “objects”. package X would basically describe static fields, methods and the static initializer.

Regards,

Roland

martin odersky

unread,
Jan 29, 2013, 2:28:09 PM1/29/13
to scala-internals
I think before we do a hack like this (and everything needing an annotation is essentially a hack), we should seriously consider the alternative: always generate java-static fields and methods for members of a globally accessible object.  It would make all problems go away, will probably give us a modest performance gain, and is from the user standpoint by far the simplest. It's also the hardest to implement but that's the right tradeoff IMO.

 - Martin
Martin Odersky
Prof., EPFL and Chairman, Typesafe
PSED, 1015 Lausanne, Switzerland
Tel. EPFL: +41 21 693 6863
Tel. Typesafe: +41 21 691 4967

Roland Kuhn

unread,
Jan 29, 2013, 2:36:01 PM1/29/13
to scala-i...@googlegroups.com
I know this is pushing it, but it is so tempting: does this including emitting static inner classes where possible? You know I would _really_ like that …

But in any case we will need a way to express that something needs to be static so the compilation run fails if it doesn’t meet the requirements (like @tailrec or @inline).

Regards,

Roland

Simon Ochsenreither

unread,
Jan 29, 2013, 3:02:47 PM1/29/13
to scala-i...@googlegroups.com

I think before we do a hack like this (and everything needing an annotation is essentially a hack), we should seriously consider the alternative: always generate java-static fields and methods for members of a globally accessible object.  It would make all problems go away, will probably give us a modest performance gain, and is from the user standpoint by far the simplest. It's also the hardest to implement but that's the right tradeoff IMO.

Sounds like an interesting idea. As usual, my concerns about the impact on class-file size apply. :-)

Adriaan Moors

unread,
Jan 29, 2013, 5:00:29 PM1/29/13
to scala-i...@googlegroups.com
In what way do you expect this to significantly impact bytecode size?

As I understand it, we're roughly just swapping the location of the method body around:
it'll move from an instance method in the module class to a static method in the instance class

the only net addition i see is the protected accessors I mentioned in my earlier message.


On Tue, Jan 29, 2013 at 12:02 PM, Simon Ochsenreither <simon.och...@gmail.com> wrote:

I think before we do a hack like this (and everything needing an annotation is essentially a hack), we should seriously consider the alternative: always generate java-static fields and methods for members of a globally accessible object.  It would make all problems go away, will probably give us a modest performance gain, and is from the user standpoint by far the simplest. It's also the hardest to implement but that's the right tradeoff IMO.

Sounds like an interesting idea. As usual, my concerns about the impact on class-file size apply. :-)

--

Kevin Wright

unread,
Jan 29, 2013, 6:34:17 PM1/29/13
to scala-i...@googlegroups.com
If anything, I'd expect it to reduce both bytecode size and class count.

For methods that can be expressed as statics (e.g. they're not inherited), there would be no need to generate the static forwarders.

In cases where *all* the methods of a singleton could be expressed as statics, it should be possible to avoid generating the singleton's class file entirely.

--
Kevin Wright
mail: kevin....@scalatechnology.com
gtalk / msn : kev.lee...@gmail.com
vibe / skype: kev.lee.wright
steam: kev_lee_wright

"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

martin odersky

unread,
Jan 30, 2013, 1:55:12 AM1/30/13
to scala-internals
On Wed, Jan 30, 2013 at 12:34 AM, Kevin Wright <kev.lee...@gmail.com> wrote:
If anything, I'd expect it to reduce both bytecode size and class count.

For methods that can be expressed as statics (e.g. they're not inherited), there would be no need to generate the static forwarders.

In cases where *all* the methods of a singleton could be expressed as statics, it should be possible to avoid generating the singleton's class file entirely.


You still need to generate it because you might want to use the object as a value elsewhere. But you don't need to load it if that's not the case.

 - Martin



--

Kevin Wright

unread,
Jan 30, 2013, 3:20:23 AM1/30/13
to scala-i...@googlegroups.com

I was thinking that we could fake the existence of the companion object in the same way that we do with java interop. But, of course, we can't pass *those* around as instances.

What if we could, however? It would allow for a reduction in the number of classes emitted for companions, AND it would make interop more powerful.

Two for the - admittedly high - price of one :)

Paul Phillips

unread,
Jan 30, 2013, 5:13:23 AM1/30/13
to scala-i...@googlegroups.com
On Wed, Jan 30, 2013 at 12:20 AM, Kevin Wright <kev.lee...@gmail.com> wrote:

I was thinking that we could fake the existence of the companion object in the same way that we do with java interop. But, of course, we can't pass *those* around as instances.

What if we could, however? It would allow for a reduction in the number of classes emitted for companions, AND it would make interop more powerful.

Two for the - admittedly high - price of one :)

With some struggling, I believe I have decoded the above. Are you suggesting something like this:

class Foo {
  private Foo MODULE$ = new Foo  // the instance of Foo, the object

  public void f1();            // a method from Foo, the class
  public static void f2();   // a method from Foo, the object
}

If so, this breaks down in a number of ways. Namespace collisions; jvm restrictions; the fact that Foo, the object, winds up with all of Foo, the class's, methods. There's no realistic way to avoid two classes given scala language semantics.

Or perhaps you are suggesting something else (but then what would "a reduction in the number of classes emitted for companions" mean?); your elaboration would spare me further struggles.

Kevin Wright

unread,
Jan 30, 2013, 6:02:13 AM1/30/13
to scala-i...@googlegroups.com
More plainly then.

We can already view a Java class as both a singleton and a "regular" class.  It's not perfect though, as "synthetic" companions like this can't be passed around as instances.

But what if we had a mechanism in the compiler so they *could* be passed around like this?  Then we could  push singleton methods back into statics of the companion class, essentially the reverse of how we expose Java statics as singletons.

I'm not suggesting that this be done for ALL singleton methods, just those where there's no possibility for a namespace collision.  I also don't see any problem with instance methods being visible to static methods.  Static methods in Java already can't call instance methods (but there is a risk of shadowing, which I hope the compiler could avoid for us)

How about if we only did this in specific circumstances?

1) For a singleton and its companion, the companion must either be final or undefined - otherwise we risk namespace pollution for potential future subclasses, and maybe a nightmare of binary incompatibility

2) ALL methods in the singleton MUST be eligible to be made static

3) There must be no name collisions between the singleton and its companion

That should simplify the implementation, and only create classes that have a direct analogy in Java code.  I'd also like to see an annotation to double-check my assumptions when creating such a class, in the same way that we do with @tailrec

Paul Phillips

unread,
Jan 30, 2013, 7:03:08 AM1/30/13
to scala-i...@googlegroups.com

On Wed, Jan 30, 2013 at 3:02 AM, Kevin Wright <kev.lee...@gmail.com> wrote:
I'm not suggesting that this be done for ALL singleton methods, just those where there's no possibility for a namespace collision.  I also don't see any problem with instance methods being visible to static methods.

The problem isn't that they're visible to the static methods, but that they're visible to everyone else.

class Foo { def f1() = 5 }
object Foo { def f2() = 10 }

If there is a single class Foo containing both methods, then I take it this is an instance of Foo:

var x: Foo.type = Foo

In scala the object Foo has no f1() method. Maybe you are thinking that we use trickery so that object Foo seems only to contain the static methods. In that case, what will you do about this:

def f(x: Any) = x match { case y: Foo => y.f1() } ; f(Foo)

Again assuming I'm understanding you correctly, this is only the tip of the iceberg.

Kevin Wright

unread,
Jan 30, 2013, 7:15:25 AM1/30/13
to scala-i...@googlegroups.com
On 30 January 2013 12:03, Paul Phillips <pa...@improving.org> wrote:

On Wed, Jan 30, 2013 at 3:02 AM, Kevin Wright <kev.lee...@gmail.com> wrote:
I'm not suggesting that this be done for ALL singleton methods, just those where there's no possibility for a namespace collision.  I also don't see any problem with instance methods being visible to static methods.

The problem isn't that they're visible to the static methods, but that they're visible to everyone else.

class Foo { def f1() = 5 }
object Foo { def f2() = 10 }

If there is a single class Foo containing both methods, then I take it this is an instance of Foo:

var x: Foo.type = Foo

In scala the object Foo has no f1() method. Maybe you are thinking that we use trickery so that object Foo seems only to contain the static methods.

Exactly, I was imagining trickery so that the singleton only exposes static methods AND the class only exposes non-static methods.  Ideally the two companions could be seen as separate all the way down the compiler stack, right up until you reach codegen.
 
In that case, what will you do about this:

def f(x: Any) = x match { case y: Foo => y.f1() } ; f(Foo)

Again assuming I'm understanding you correctly, this is only the tip of the iceberg.


Is that not just a match failure? because Foo-the-singleton isn't an instance of Foo-the-class
 

Paul Phillips

unread,
Jan 30, 2013, 7:20:48 AM1/30/13
to scala-i...@googlegroups.com

On Wed, Jan 30, 2013 at 4:15 AM, Kevin Wright <kev.lee...@gmail.com> wrote:
Is that not just a match failure? because Foo-the-singleton isn't an instance of Foo-the-class

You mean in our "tricky overlay" it isn't an instance of it. But it really is, i.e. the bytecode instruction instanceof says yes. If the bytecode says it is an instance of Foo, scala has no basis for saying otherwise, and no means by which to distinguish "Foo the object" from an instance of "Foo the class".

√iktor Ҡlang

unread,
Jan 30, 2013, 7:52:40 AM1/30/13
to scala-i...@googlegroups.com
Quick thought about the "mismatch in lexical scope and init ordering issue", how about only allowing it in early initializer block?

class Foo(...) extends {
  @static val staticMember = …
} with SomeClass {
  val normalMember = …
}


--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Viktor Klang
Director of Engineering

Typesafe - The software stack for applications that scale
Twitter: @viktorklang

Kevin Wright

unread,
Jan 30, 2013, 7:53:29 AM1/30/13
to scala-i...@googlegroups.com
Jinkies!

Yes, that's a fiddly one.  What if Foo-the-singleton never actually need to exist at all at runtime?

If we restrict the static optimisation to only those singletons that don't inherit from anything, there would never be any need to *really* pass instances around at runtime.  Without instances the can be no instanceOf check, the whole thing becomes a compile-time illusion.

Johannes Rudolph

unread,
Jan 30, 2013, 8:00:58 AM1/30/13
to scala-i...@googlegroups.com
On Wed, Jan 30, 2013 at 1:20 PM, Paul Phillips <pa...@improving.org> wrote:
> You mean in our "tricky overlay" it isn't an instance of it. But it really
> is, i.e. the bytecode instruction instanceof says yes. If the bytecode says
> it is an instance of Foo, scala has no basis for saying otherwise, and no
> means by which to distinguish "Foo the object" from an instance of "Foo the
> class".

Sounds like a similar problem as you have with value classes. Meaning
you would need boxing in some cases but not in others. Maybe you could
even use just one wrapper class with a tag for all singleton object
types.

--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

Paul Phillips

unread,
Jan 30, 2013, 8:21:36 AM1/30/13
to scala-i...@googlegroups.com

On Wed, Jan 30, 2013 at 4:53 AM, Kevin Wright <kev.lee...@gmail.com> wrote:
If we restrict the static optimisation to only those singletons that don't inherit from anything, there would never be any need to *really* pass instances around at runtime.

var sentinel: AnyRef
def setSentinel(x: AnyRef) = sentinel = AnyRef
def checkSentinel(y: AnyRef) = sentinel eq y

object Bar
object Foo
setSentinel(Foo)
checkSentinel(Foo)
checkSentinel(Bar)

You will be hard-pressed to elude the need for an instance. There is no compile-time trickery possible which can eliminate the need to perform reference comparisons at runtime.

Paul Phillips

unread,
Jan 30, 2013, 8:25:46 AM1/30/13
to scala-i...@googlegroups.com

On Wed, Jan 30, 2013 at 5:00 AM, Johannes Rudolph <johannes...@googlemail.com> wrote:
Sounds like a similar problem as you have with value classes. Meaning
you would need boxing in some cases but not in others. Maybe you could
even use just one wrapper class with a tag for all singleton object
types.

Hmm. Maybe after there are about fifty fewer value class bugs open this will be more tempting to think about...

Josh Suereth

unread,
Jan 30, 2013, 10:14:48 AM1/30/13
to scala-internals
Or you can go with some CRAZY syntax:

class Foo extends { /* early init */ } 
  with Bar  // Class or Trait
  with Baz 
  // Now we have a pseudo-trait that has a nested block inside it
  with Static({
     // here is the 'static init' block.  We can see things here in the class, but not vice versay
     // This is essentially like having a java static {} block, except all values/variables, etc. are promoted to 
     // Statics.
     //  The *odd* bit here is you can't use constructor arguments in this static block.
  }) {
 // Here is the regular class definition
}

In any case, any instantiations of "Static" outside of class definition are blown to hell.   I'm really not a huge fan of this kind of ugly in Scala, but if we want to support the same kind of ugly from Java, I think an approach like this (where you try to make access rules and semantics follow *as closely* as possible to expectations) is the best way to go.

Essentially, we need some way to define the static initializer for a class without confusing it for the constructor.  To do so, it needs to be outside the class body.   The above is a random idea thrown together hastily, but I'm sure with some thought it might look a bit better....


- Josh


--

√iktor Ҡlang

unread,
Jan 30, 2013, 10:20:50 AM1/30/13
to scala-i...@googlegroups.com
Or even:

@static({
  val staticFooInt = 5
}) class Foo(...) {
  body of class
}
--
Viktor Klang
Director of Engineering

Typesafe - The software stack for applications that scale
Twitter: @viktorklang

Ittay Dror

unread,
Jan 30, 2013, 10:28:10 AM1/30/13
to scala-i...@googlegroups.com, Josh Suereth
if we're talking crazy, how about having a 'java{}' construct (like C had assembly). which means the java code is compiled (with java's compiler) and added as-is to the class (not sure if this can be done...). then the user needs to know what they're doing, but maybe the static-needing crowed is already in that camp. if so, it opens up doors to other options.

Josh Suereth

unread,
Jan 30, 2013, 10:57:56 AM1/30/13
to scala-internals
Yep, that's the same idea.

Paul Phillips

unread,
Jan 30, 2013, 11:18:47 AM1/30/13
to scala-i...@googlegroups.com, Josh Suereth

On Wed, Jan 30, 2013 at 7:28 AM, Ittay Dror <ittay...@gmail.com> wrote:
if we're talking crazy, how about having a 'java{}' construct (like C had assembly). which means the java code is compiled (with java's compiler) and added as-is to the class (not sure if this can be done...). then the user needs to know what they're doing, but maybe the static-needing crowed is already in that camp. if so, it opens up doors to other options.

I've thought about doing this for years. A complete implementation would be difficult, but a one-way trip wouldn't be:

java"""
  public class Bippy {
    public static String feelingStatic = "a";
  }
"""

I don't know a lot about type macros, but as far as I know that's the missing piece of this puzzle. Given string interpolation, regular macros, the jdk compiler api, and type macros, inline assembly/java should be fully realizable without new hacks - and we could do a lot more than inline literal java code (although that alone would solve a lot of problems.)

Of course, we shouldn't settle for java. It would be better (except in terms of familiarity, which I understand is important) to use a language which maps directly onto bytecode, since that's the whole reason we'd be dropping below scala in the first place. Mirah maybe, or something we design for this purpose. As much as we like to call java "assembly language", it's a pretty poor assembly language.

Jonas Bonér

unread,
Jan 30, 2013, 11:38:24 AM1/30/13
to scala-i...@googlegroups.com, Josh Suereth
Sounds extremely useful. But I would be surprised if it is not harder
than it sounds. Th devil is in the details.

>
> --
> You received this message because you are subscribed to the Google Groups
> "scala-internals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to scala-interna...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>



--
Jonas Bonér
Phone: +46 733 777 123
Home: http://jonasboner.com
Twitter: @jboner

James Iry

unread,
Jan 30, 2013, 12:20:48 PM1/30/13
to scala-i...@googlegroups.com
A google for "Java bytecode assembler" reveals several languages in various states of abandonment and disrepair. 

Simon Ochsenreither

unread,
Jan 30, 2013, 12:29:33 PM1/30/13
to scala-i...@googlegroups.com, Josh Suereth

Of course, we shouldn't settle for java. It would be better (except in terms of familiarity, which I understand is important) to use a language which maps directly onto bytecode, since that's the whole reason we'd be dropping below scala in the first place. Mirah maybe, or something we design for this purpose. As much as we like to call java "assembly language", it's a pretty poor assembly language.

F# has something like that! Most people know the quotations for typed expressions <@ 1 + %expr @> and untyped expressions <@@ 1 + %%expr @@>, but most people don't know that F# has also CLI quotations: (# cli instructions #). :-)

I pretty much agree with that. All I want is that my bytecode looks in a certain way, I don't want to pay for it by importing dozens of Java-idioms and initialization headaches with it.
I think it would be even better to not have @static or any other user-facing mechanism, as long as macros/the compiler API allow me to do what I want.

I'm still wondering if the non-effect of setting the STATIC flag is a bug, or if I'm missing something here (like that STATIC is used to mark items which qualify as “stable” paths to something).
If we can't make STATIC work, it would be nice to have some introduceStaticMember method, just like we have introduceTopLevel etc.

Bye,

Simon
Reply all
Reply to author
Forward
0 new messages