Scala valor de instancia de alcance

Tenga en cuenta que esta pregunta y otras similares se han formulado anteriormente, como enReferencias hacia adelante: ¿por qué se compila este código?, pero encontré las respuestas para dejar algunas preguntas abiertas, así que tengo otra oportunidad en este problema.

Dentro de los métodos y funciones, el efecto de laval palabra clave parece ser léxico, es decir,

<code>def foo {
  println(bar)
  val bar = 42
}
</code>

flexible

<code>error: forward reference extends over definition of value bar
</code>

Sin embargo, dentro de las clases, las reglas de alcance deval parecen cambiar

<code>object Foo {
  def foo = bar
  println(bar)
  val bar = 42
}
</code>

Esto no solo compila, sino que tambiénprintln en el constructor cederá0 como su salida, mientras se llamafoo después de que la instancia se haya construido completamente, se obtendrá el valor esperado42.

Por lo tanto, parece que es posible que los métodos remitan los valores de la instancia, los cuales, eventualmente, se inicializarán antes de que se pueda llamar al método (a menos que, por supuesto, lo esté llamando desde el constructor), y para las declaraciones dentro del constructor para remitir valores de referencia de la misma manera, accediendo a ellos antes de que se hayan inicializado, lo que resulta en un valor arbitrario tonto.

De esto surgen un par de preguntas:

Por queval ¿Usa su efecto léxico de compilación en los constructores?

Dado que un constructor es en realidad solo un método, esto parece bastante inconsistente para descartar por completovalEl efecto en tiempo de compilación, que le otorga solo su efecto habitual en tiempo de ejecución.

Por quevalEfectivamente, pierde el efecto de declarar uninmutable ¿valor?

Acceder al valor en diferentes momentos puede resultar en diferentes resultados. Para mí, parece que se está filtrando un detalle de implementación del compilador.

¿Cómo podrían ser las causas de uso legítimas para esto?

Me está costando encontrar un ejemplo que requiera absolutamente la semántica actual deval dentro de los constructores y no sería fácilmente implementable con un adecuado, léxicoval, posiblemente en combinación conlazy.

¿Cómo se podría evitar este comportamiento deval¿Recuperar todas las garantías de las que uno está acostumbrado a usarlo en otros métodos?

Uno podría, presumiblemente, declarar todas las instancias.vals para serlazy con el fin de volver a unaval ser inmutable y obtener el mismo resultado sin importar cómo se acceda a ellos y hacer que el efecto de compilación que se observa en los métodos regulares sea menos relevante, pero eso me parece un truco para este tipo de cosas.

Dado que es poco probable que este comportamiento cambie en el lenguaje real, ¿sería un complemento del compilador el lugar correcto para solucionar este problema, o es posible implementar unval¿una palabra clave similar con, para alguien que acaba de pasar una hora depurando un problema causado por esta rareza, una semántica más sensible dentro del lenguaje?

Respuestas a la pregunta(2)

Su respuesta a la pregunta