-
Notifications
You must be signed in to change notification settings - Fork 19
Offer optimistic locking for lazy vals #10
Comments
What about a |
@jdegoes that's a sensible idea. |
The real winner with lazy vals would be to rescue the 90+% of lazy vals which are not intended to be lazy from paying synchronization costs on every access until the end of time. It's pretty nuts if you think about it. Very few of the lazy vals I have seen in the wild (and I have seen a lot of them) are lazy because it's relevant that the evaluation is delayed. They are lazy to avoid NPEs and cycles. The two major brands of problem which you would encounter if there were no lazy vals are inter-file (mixin composition) and intra-file, as in e.g. Definitions.scala, any nontrivial parser combinator, etc etc. The first one is probably hard, but the second one isn't. The compiler can do the dependency analysis of what needs to come before what and then just order them. All you need is a way for the user to indicate it. |
@paulp Good point, though is the dependency analysis genuinely easy? What if a val calls a virtual method whose implementation isn't known at compile time, and refers to something else in the dependency graph? |
@propensive It's easy because it's impossible for the compiler to do anything with that, so you won't be surprised to find the burden is on you. It's the kind of thing you'd opt into and which would come with warning labels (and it could tell you useful things like the set of unknown method implementations to which you are vulnerable.) |
@paulp Seems reasonable. So we'd replace all the lazy vals with @reorderable vals (or something like that), and the compiler would give us a load of warnings whenever we refer to something it can't analyze? Apart from my unverified suspicion that you just wouldn't be able to do anything useful most of the time with such a constraint, I'm very much in favor of it as a solution. |
@jdegoes @puffnfresh I'd love a @pure annotation too if we could actually make use of it. But purity analysis is nontrivial (though could be framed as a dependent-typing problem, maybe?) and I'm tempted to believe it wouldn't be useful most of the time. Nevertheless, I really think it should be explored. |
@propensive A |
In that case I already implemented it: scala#2416 |
Remove trace macro. Too unstable.
@jdegoes I wouldn't want to rule out the possibility of a checked |
+1 (are +1's helpful? I know they're not as helpful as pull requests...) |
Rather than in implementation of the abstract method in the expanded anonymous class. This leads to more more efficient use of the constant pool, code shapes more amenable to SAM inlining, and is compatible with the old behaviour of `-Xexperimental` in Scala 2.11, which ScalaJS now relies upon. Manual test: ``` scala> :paste -raw // Entering paste mode (ctrl-D to finish) package p1; trait T { val x = 0; def apply(): Any }; class DelambdafyInline { def t: T = (() => "") } // Exiting paste mode, now interpreting. scala> :javap -c p1.DelambdafyInline Compiled from "<pastie>" public class p1.DelambdafyInline { public p1.T t(); Code: 0: new scala#10 // class p1/DelambdafyInline$$anonfun$t$1 3: dup 4: aload_0 5: invokespecial scala#16 // Method p1/DelambdafyInline$$anonfun$t$1."<init>":(Lp1/DelambdafyInline;)V 8: areturn public final java.lang.Object p1$DelambdafyInline$$$anonfun$1(); Code: 0: ldc scala#22 // String 2: areturn public p1.DelambdafyInline(); Code: 0: aload_0 1: invokespecial scala#25 // Method java/lang/Object."<init>":()V 4: return } scala> :javap -c p1.DelambdafyInline$$anonfun$t$1 Compiled from "<pastie>" public final class p1.DelambdafyInline$$anonfun$t$1 implements p1.T,scala.Serializable { public static final long serialVersionUID; public int x(); Code: 0: aload_0 1: getfield scala#25 // Field x:I 4: ireturn public void p1$T$_setter_$x_$eq(int); Code: 0: aload_0 1: iload_1 2: putfield scala#25 // Field x:I 5: return public final java.lang.Object apply(); Code: 0: aload_0 1: getfield scala#34 // Field $outer:Lp1/DelambdafyInline; 4: invokevirtual scala#37 // Method p1/DelambdafyInline.p1$DelambdafyInline$$$anonfun$1:()Ljava/lang/Object; 7: areturn public p1.DelambdafyInline$$anonfun$t$1(p1.DelambdafyInline); Code: 0: aload_1 1: ifnonnull 6 4: aconst_null 5: athrow 6: aload_0 7: aload_1 8: putfield scala#34 // Field $outer:Lp1/DelambdafyInline; 11: aload_0 12: invokespecial scala#42 // Method java/lang/Object."<init>":()V 15: aload_0 16: invokespecial scala#45 // Method p1/T.$init$:()V 19: return } scala> :quit ``` Adriaan is to `git blame` for `reflection-mem-typecheck.scala`.
To resurrect this issue, please rework it as an issue/PR against Lightbend Scala (ie. scala/scala). |
The text was updated successfully, but these errors were encountered: