Sobre as atribuições e métodos de configuração do Scala

Edit: O bug que levou esta perguntafoi corrigido.

Na Referência Scala, eu posso ler (p. 86):

A interpretação de uma atribuição a uma variável simples x = e depende da definição de x. Se x denota uma variável mutável, a atribuição altera o valor atual de x para ser o resultado da avaliação da expressão e. O tipo de e deve estar em conformidade com o tipo de x. Se x é uma função sem parâmetros definida em algum modelo e o mesmo modelo contém uma função de configuração x_ = como membro, a atribuição x = e é interpretada como a chamada x _ = (e) dessa função de configuração. Analogamente, uma atribuição f .x = e a uma função sem parâmetros x é interpretada como a invocação f.x _ = (e).

Então, por exemplo, algo assim funciona bem:

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

Eu posso escrever

val a = new A
a.a = 10

Mas se eu definir a classe assim, adicionando um parâmetro de tipo ao método a:

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

então não funciona mais; Eu recebo umerror: reassignment to val se eu escrevera.a = 10. Engraçado, ainda funciona sem parâmetro de tipo e uma lista de parâmetros implícita, por exemplo.

Indiscutivelmente, neste exemplo, o parâmetro type não é muito útil, mas no design de DSLs, seria ótimo chamar o método setter mesmo se o getter tiver parâmetros de tipo (e, a propósito, adicionar parâmetros de tipo no setter é permitido e funciona bem).

Então, eu tenho três perguntas:

Existe uma solução alternativa?O comportamento atual deve ser considerado um bug?Por que o compilador aplica um método getter para permitir o uso do açúcar sintático para o setter?

ATUALIZAR

Aqui está o que estou realmente tentando fazer. É bastante longo, desculpe, eu pretendia evitá-lo, mas percebi que era mais confuso omiti-lo.

Estou projetando GUIs com SWT em Scala e me divertindo muito usando o Dave Orme'sXScalaWT, o que reduz imensamente a quantidade de código necessário. Aqui está um exemplo de sua postagem no blog sobre como criar um SWTComposite que converte ° C em ° F graus:

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) })
  )
)

O argumento para cada um dos métodos de construção de widget é do tipo(WidgetType => Any)*, com algumas conversões implícitas úteis, que permitem, por exemplo, especificar diretamente uma string para widgets que possuem umsetText() método. Todas as funções do construtor são importadas de um objeto singleton.

No final, eu gostaria de poder escrever algo nesse sentido:

val fieldEditable = new WritableValue // observable value

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

Isso vincularia a propriedade editável do campo de texto à seleção da caixa de seleção por meio da variável WritableValue.

Primeiro: argumentos nomeados não são aplicáveis aqui, então a linhaeditable = false tem que vir de algum lugar. Assim, ao longo dos métodos de construção de widget no objeto singleton, eu poderia escrever, conceitualmente,

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

... mas isso funciona apenas se o getter também estiver presente. Ótimo: eu precisaria do getter de qualquer maneira para implementar a ligação de dados com <=>. Algo assim:

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

Se isso funcionasse, a vida seria boa, porque eu posso definir <=> no BindingMaker e posso usar essa boa sintaxe. Mas, infelizmente, o parâmetro type no getter quebra o setter. Daí minha pergunta original: por que esse parâmetro de tipo simples afetaria se o compilador decide ir adiante com o açúcar sintático para chamar o setter?

Espero que isso torne um pouco mais claro agora. Obrigado pela leitura.

questionAnswers(1)

yourAnswerToTheQuestion