Fiz sua pergunta como por que não projetar o idioma para evitar a necessidade de uma convenção em primeiro lugar? Em outras palavras, por que Scala não força o uso de parênteses o tempo todo, em vez de permitir que os programadores os omitam às vezes?
A resposta é encontrada em transparência referencial . Essencialmente, se uma função não tiver efeitos colaterais, uma chamada de função poderá ser substituída pelo resultado, sem alterar o comportamento do programa.
Isso significa que uma função sem parâmetros ou efeitos colaterais é semanticamente equivalente a val
manter o valor de retorno dessa função. Devido a essa propriedade, à medida que a classe evolui, o programador pode alternar entre val
usar uma função ou usar uma função, conforme a conveniência ou a eficiência exigir.
Como você pode omitir os parênteses, isso significa que a chamada de código para algo como queue.size
não precisa saber nem se importar se size
é uma função ou a val
. O implementador da Queue
classe é, portanto, livre para alterar entre os dois sem precisar alterar nenhum código de chamada (embora eu acredite que seja necessário recompilar). Ele estabiliza a interface pública da classe. Por exemplo, você pode iniciar um queue.size
chamando size
um subjacente List
, que é potencialmente O(n)
, e depois mudar size
para a val
por motivos de eficiência.
A convenção sugere os parênteses quando há efeitos colaterais para deixar claro que esse membro da classe é definitivamente uma chamada de função e, portanto, potencialmente não é referencialmente transparente. É importante chamar o código para saber se os efeitos colaterais são produzidos, para evitar chamá-lo repetidamente. Se você não se importa se é uma função ou não, é melhor tratá-la como se não fosse.