Closed
Conversation
Avoid class initialization traps in the object wrapper by
extending App.
Previously, the following line would hang in the REPL
because the parallel operation was started from the constructor
of the wrapping object, i.e., from the static initializer of
the class. Class-loading the closure would deadlock on loading
the wrapper, which in turn blocks on completion of the par.map.
```
scala> def i = 42 ; List(1, 2, 3).par.map(x => x + i)
```
Any user code that starts a thread could deadlock, including
innocent experiments with Futures in for comprehensions.
The App object is initialized in the usual place, namely
the print method of the eval object, by invoking main.
(A lazy `compute` accommodates two paths of evaluation:
`print` for REPL, `result` for script engine.)
A compiler option `-YreplWrap` takes values "class", "object"
and "app" (default) to select the wrapper template.
```
scala> 42 // show
object $read extends scala.AnyRef {
def <init>() = {
super.<init>;
()
};
object $iw extends App {
def <init>() = {
super.<init>;
()
};
val res0 = 42
};
}
[[syntax trees at end of typer]] // <console>
package $line3 {
object $read extends scala.AnyRef {
def <init>(): $line3.$read.type = {
$read.super.<init>();
()
};
object $iw extends AnyRef with App {
def <init>(): type = {
$iw.super.<init>();
()
};
private[this] val res0: Int = 42;
<stable> <accessor> def res0: Int = $iw.this.res0
}
}
}
[[syntax trees at end of typer]] // <console>
package $line3 {
object $eval extends scala.AnyRef {
def <init>(): $line3.$eval.type = {
$eval.super.<init>();
()
};
<stable> <accessor> lazy def compute: Unit = $line3.$read.$iw.main(null);
lazy private[this] var $result: Int = _;
<stable> <accessor> lazy def $result: Int = {
$eval.this.$result = {
$eval.this.compute;
$line3.$read.$iw.res0
};
$eval.this.$result
};
lazy private[this] var $print: String = _;
<stable> <accessor> lazy def $print: String = {
$eval.this.$print = {
$eval.this.compute;
"res0: Int = ".+(scala.runtime.ScalaRunTime.replStringOf($line3.$read.$iw.res0, 1000))
};
$eval.this.$print
}
}
}
res0: Int = 42
```
`-Yrepl-wrap:object` is the default.
Now `valueOfTerm` drills down reflectively using the `fullName` of the desired symbol. It respects a prefix of static modules, but switches to instance mirrors as required. The target is an accessor on the last enclosing instance.
Contributor
Author
|
Check reduced nesting against the behavior in https://issues.scala-lang.org/browse/SI-9208 ... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The PR title reminds me of Whitney Houston's infamous declaration, "Crack is whack."
This updates #4311 for 2.12.