Acerca de las tareas y métodos de establecimiento de Scala

Editar: el error que provocó esta preguntaahora ha sido reparado.

En la referencia de Scala, puedo leer (p. 86):

La interpretación de una asignación a una variable simple x = e depende de la definición de x. Si x denota una variable mutable, entonces la asignación cambia el valor actual de x para ser el resultado de evaluar la expresión e. Se espera que el tipo de e se ajuste al tipo de x. Si x es una función sin parámetros definida en alguna plantilla, y la misma plantilla contiene una función de establecimiento x_ = como miembro, entonces la asignación x = e se interpreta como la invocación x _ = (e) de esa función de establecimiento. Análogamente, una asignación f .x = e a una función sin parámetros x se interpreta como la invocación f.x _ = (e).

Entonces, por ejemplo, algo como esto funciona bien:

class A {
  private var _a = 0
  def a = _a
  def a_=(a: Int) = _a = a
}

Entonces puedo escribir

val a = new A
a.a = 10

Pero si defino la clase de esta manera, agrego un parámetro de tipo al método a:

class A {
  private var _a = 0
  def a[T] = _a
  def a_=(a: Int) = _a = a
}

entonces ya no funciona; Consigo unerror: reassignment to val si yo escriboa.a = 10. Curiosamente, todavía funciona sin parámetros de tipo y una lista de parámetros implícitos, por ejemplo.

Podría decirse que, en este ejemplo, el parámetro de tipo no es muy útil, pero en el diseño de DSL, sería genial tener el método setter llamado incluso si el getter tiene parámetros de tipo (y por cierto, agregar parámetros de tipo en el setter está permitido y funciona bien).

Entonces tengo tres preguntas:

¿Hay alguna solución?¿Debería considerarse el comportamiento actual como un error?¿Por qué el compilador impone un método getter para permitir el uso del azúcar sintáctico para el setter?

ACTUALIZAR

Esto es lo que realmente estoy tratando de hacer. Es bastante largo, lo siento, quise evitarlo, pero me di cuenta de que era más confuso omitirlo.

Estoy diseñando interfaces gráficas de usuario con SWT en Scala y divirtiéndome enormemente con Dave Orme'sXScalaWT, que reduce enormemente la cantidad de código necesario. Aquí hay un ejemplo de su publicación de blog sobre cómo crear un SWTComposite que convierte ° C a ° F grados:

var fahrenheit: Text = null
var celsius: Text = null

composite(
  _.setLayout(new GridLayout(2, true)),

  label("Fahrenheit"),
  label("Celsius"),

  text(fahrenheit = _),
  text(celsius = _),

  button(
    "Fahrenheit => Celsius",
    {e : SelectionEvent => celcius.setText((5.0/9.0) * (fahrenheit - 32)) }
  ),
  button(
    "Celsius -> Fahrenheit",
    {e : SelectionEvent => fahrenheit.setText((9.0/5.0) * celsius + 32) })
  )
)

El argumento para cada uno de los métodos de construcción de widgets es de tipo(WidgetType => Any)*, con algunas conversiones implícitas útiles, que por ejemplo permiten especificar directamente una cadena para widgets que tienen unsetText() método. Todas las funciones de constructor se importan de un objeto singleton.

Al final, me gustaría poder escribir algo en esta línea:

val fieldEditable = new WritableValue // observable value

composite(
  textField(
    editable <=> fieldEditable,
    editable = false
  ),
  checkbox(
    caption = "Editable",
    selection <=> fieldEditable
  )
)

Esto vincularía la propiedad editable del campo de texto a la selección de la casilla de verificación a través de la variable WritableValue.

Primero: los argumentos con nombre no son aplicables aquí, entonces la líneaeditable = false tiene que venir de alguna parte Entonces, a lo largo de los métodos de construcción de widgets en el objeto singleton, podría escribir, conceptualmente,

def editable_=[T <: HasEditable](value: Boolean) = (subject: T) => subject.setEditable(value)

... pero esto funciona solo si el captador también está presente. Genial: necesitaría el getter de todos modos para implementar el enlace de datos con <=>. Algo como esto:

def editable[T <: HasEditable] = new BindingMaker((widget: T) => SWTObservables.observeEditable(widget))

Si esto funcionara, la vida sería buena porque entonces puedo definir <=> en BindingMaker y puedo usar esta buena sintaxis. Pero, por desgracia, el parámetro de tipo en el getter rompe el setter. De ahí mi pregunta original: ¿por qué este simple parámetro de tipo afectaría si el compilador decide seguir adelante con el azúcar sintáctico para llamar al setter?

Espero que esto lo aclare un poco más ahora. Gracias por leer…

Respuestas a la pregunta(1)

Su respuesta a la pregunta