Métodos Parameterless & Empty-Paren no Scala

10

Estou aprendendo Scala no momento através do Scala de programação de Odersky (2º). Estou no capítulo 10, onde ele começa a introduzir métodos sem parâmetros e parênteses vazios. Eu simplesmente não consigo entender.

Até agora, tudo o que entendo é que devo usar parênteses vazios se um método tiver efeitos colaterais e métodos sem parâmetros.

Não consigo descobrir qual é a vantagem desta convenção. Li as postagens no Stack Exchange, mas, para ser sincero, quando as postagens começaram a discutir esse tópico com certa profundidade, fiquei perdido.

Estou procurando uma explicação simples de quais são os casos de uso típicos desse recurso de idioma e quais são as vantagens para me ajudar a entendê-lo melhor.


fonte

Respostas:

14

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 valmanter o valor de retorno dessa função. Devido a essa propriedade, à medida que a classe evolui, o programador pode alternar entre valusar 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.sizenão precisa saber nem se importar se sizeé uma função ou a val. O implementador da Queueclasse é, 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.sizechamando sizeum subjacente List, que é potencialmente O(n), e depois mudar sizepara a valpor 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.

Karl Bielefeldt
fonte
6

Essa é uma convenção, não faz parte do design da linguagem. É usado como uma placa de sinalização para ajudar as pessoas que precisam ler o código depois de escrevê-lo para entender melhor.

Do Guia de Estilo de Scala sobre Invocação de Método:

Scala permite a omissão de parênteses nos métodos da arity-0 (sem argumentos):

reply() 

// is the same as 

reply

No entanto, essa sintaxe deve ser usada apenas quando o método em questão não tiver efeitos colaterais (puramente funcionais). Em outras palavras, seria aceitável omitir parênteses ao chamar queue.size, mas não ao chamar println().

A observação religiosa desta convenção melhorará drasticamente a legibilidade do código e facilitará muito a compreensão imediata da operação mais básica de qualquer método. Resista ao desejo de omitir parênteses simplesmente para salvar dois caracteres!

No .NET, a convenção é usar métodos quando o código pode demorar um pouco para ser executado (por exemplo, mais de 50 ms) e propriedades (métodos essencialmente com parênteses vazios) quando não for (por exemplo, é uma pesquisa simples).

Robert Harvey
fonte