Métodos sin parámetros y de parche vacío en Scala

10

Estoy aprendiendo Scala en este momento a través de Scala de programación de Odersky (2º). Estoy hasta el capítulo 10, donde comienza a introducir métodos sin parámetros y de parche vacío. Simplemente no puedo entenderlo.

Hasta ahora, todo lo que entiendo es que debería usar paréntesis vacíos si un método tiene efectos secundarios y métodos sin parámetros de lo contrario.

No puedo entender cuál es la ventaja de esta convención. Leí las publicaciones en Stack Exchange, pero para ser honesto, cuando las publicaciones comenzaron a discutir este tema con cierta profundidad, me perdí.

Estoy buscando una explicación simple de cuáles son los casos de uso típicos de esta característica del lenguaje y cuáles son las ventajas para ayudarme a entenderlo mejor.


fuente

Respuestas:

14

Tomé su pregunta como ¿por qué no diseñar el lenguaje para evitar la necesidad de una convención en primer lugar? En otras palabras, ¿por qué Scala no solo fuerza el uso de paréntesis todo el tiempo, en lugar de permitir que los programadores los omitan a veces?

La respuesta se encuentra en la transparencia referencial . Esencialmente, si una función no tiene efectos secundarios, una llamada a función puede ser reemplazada por su resultado, sin cambiar el comportamiento del programa.

Eso significa que una función sin parámetros o efectos secundarios es semánticamente equivalente a valmantener el valor de retorno de esa función. Debido a esta propiedad, a medida que evoluciona una clase, el programador puede alternar entre usar valo usar una función, según lo dicte la conveniencia o la eficiencia.

Como puede omitir los paréntesis, eso significa que el código que llama a algo como queue.sizeno necesita saber ni importar si sizees una función o un val. El implementador de la Queueclase es, por lo tanto, libre de cambiar entre los dos sin tener que cambiar ninguno de los códigos de llamada (aunque creo que será necesario volver a compilar). Estabiliza la interfaz pública de la clase. Por ejemplo, puede comenzar queue.sizellamando sizea un subyacente List, que es potencialmente O(n), y luego cambiar sizea un valpor razones de eficiencia.

La convención sugiere los paréntesis cuando hay efectos secundarios para dejar en claro que este miembro de la clase es definitivamente una llamada a la función y, por lo tanto, potencialmente no es referencialmente transparente. Es importante que el código de llamada sepa si se producen efectos secundarios, para que puedan evitar llamarlo repetidamente. Si no le importa si es una función o no, puede tratarla como si no lo fuera.

Karl Bielefeldt
fuente
6

Esa es una convención, no parte del diseño del lenguaje. Se usa como una señal para ayudar a las personas que tienen que leer el código después de que lo escribes para entenderlo mejor.

De la Guía de estilo de Scala sobre invocación de métodos:

Scala permite la omisión de paréntesis en los métodos de arity-0 (sin argumentos):

reply() 

// is the same as 

reply

Sin embargo, esta sintaxis solo debe usarse cuando el método en cuestión no tiene efectos secundarios (puramente funcional). En otras palabras, sería aceptable omitir paréntesis al llamar queue.size, pero no al llamar println().

Observar religiosamente esta convención mejorará drásticamente la legibilidad del código y hará que sea mucho más fácil entender de un vistazo la operación más básica de cualquier método dado. ¡Resista el impulso de omitir paréntesis simplemente para salvar dos caracteres!

En .NET, la convención es usar métodos cuando el código puede tardar un tiempo en ejecutarse (por ejemplo, más de 50 ms) y propiedades (esencialmente métodos de paren vacío) cuando no lo hará (es decir, es una búsqueda simple).

Robert Harvey
fuente