Funciones en Scala, breve introducción

Una función es un conjunto de sentencias que realizan una tarea. Scala tiene tanto funciones como métodos. La mayoría de las veces no se hace distinción entre ellos, pero hay ocasiones en las que hay que tener en cuenta que no son lo mismo. Un método en Scala, como en Java, es parte de una clase. Tiene su nombre, su firma y opcionalmente anotaciones. Mientras que una función es un objecto completo, son instancias de las clases Function0, Function1, Function2,… (el número depende del número de parámetros de la función). Uno de los métodos que contienen estas clases es el método apply, que contiene el código que implementa la función y se aplica cuando hacemos una llamada la función.

La estructura básica de una función en Scala es la siguiente:


Scala method definition

La definición de la función comienza con la palabra reservada def seguida del nombre de la función. Scala define tres formas para dar un nombre valido a las funciones:

  1. Una letra seguida por números, letras o un guion bajo “_”. También se pueden finalizar con operadores (?,+,-,|,…) cuando van precedidos por un guión bajo.
  2. Un operador seguido por otros operadores.
  3. Cualquier secuencia de caracteres encerrados entre comillas.

Para clarificar estos tres tipos mostramos a continuación algunos ejemplos de nombres validos y erróneos (cada ejemplo tiene el numero de la regla a la que pertenece):

El echo de permitir utilizar operadores como nombres de funciones abre interesantes posibilidades. Por ejemplo, queremos implementar una clase que tenga un atributo de tipo string y un método de multiplicación, que cuando se llame con un paramento entero éste debería devolver un string concatenado con si mismo el número de veces especificado por el parámetro. Con la posibilidad de utilizar operadores como nombres de funciones, la implementación de esta clase podría ser la siguiente:

A continuación del nombre de la función se indica una lista de parámetros separados por comas y encerrados entre paréntesis. Al igual que en otros lenguajes podemos definir funciones sin parámetros:

Los parámetros pueden tener valores por defecto, de forma que cuando realizamos la llamada a una función sin parámetros entonces se utiliza el valor por defecto, pero si indicamos los parámetros se utilizan éstos:

Scala también permite la realización de llamadas a funciones utilizando “named parameters”, esto da la posibilidad de pasar los argumentos basados en el nombre de los parámetros, en lugar de en su posición. Named parameter ayuda a evitar confusiones entre los parámetros y a mejorar la lectura del código:

<

p style=”text-align: justify;”>Cuando queremos indicar un número variable de parámetros (vargs en Java) debemos marcar el último parámetro de la función con el operador ‘*’. El siguiente ejemplo muestra su uso:

Cuando hacemos una llamada a una función con cero o un parámetro, ésta puede ser llamada sin utilizar el punto y los paréntesis. También se puede omitir los paréntesis cuando se llama a una función que no tenga parámetros:

Debido a que Scala infiere el tipo, el resultado de la función no es obligatorio en la mayoría de los casos por lo tanto se puede omitir. Pero en el caso de las funciones recursivas es obligatorio indicar el tipo que devuelve la función, esto es debido a que Scala infiere el tipo de retorno buscando cual es la sentencia de return y le asigna el tipo de esta sentencia. Cuando tenemos una función recursiva esto no se puede realizar y para evitar posibles errores de ejecución se obliga a indicar el tipo de retorno de la función.

En Java cuando un método no devuelve ningún valor se indica con la palabra reservada void. En Scala se indica con el tipo de retorno Unit:

Por último cuando el cuerpo de la función es una sola expresión los corches no son necesarios:

Si no ponemos return el compilador asume que el resultado de la funcion es la ultima sentencia. Aunque podemos poner el return en cualquier parte de la función: