Funciones en Ceylon, segunda parte

En mi post anterior, hablé acerca de las funciones de orden superior, la manera en que se pasan referencias a métodos, cómo se invocan, etc. Pues bien, ha habido bastante progreso en Ceylon, en varias áreas, y una de las que considero importantes es precisamente el manejo de funciones; algunas de las cosas que mencioné en ese post han cambiado, mientras que ha surgido funcionalidad nueva que no estaba disponible previamente. Así que veamos los cambios:

Callables

Primero que nada, ya no tenemos la restricción de que un   no podía ser invocado; ahora ya se puede, por lo que esto ya es válido:

 

La otra forma sigue siendo igual de válida:

 

Argumentos por nombre

En Ceylon hay dos formas de hacer una invocación: usando argumentos posicionales (que es la manera en que todo mundo está acostumbrado a hacerlo) o usando argumentos nombrados (que no todos los lenguajes tienen y los que lo tienen, usan distintas sintaxis).

Este es un ejemplo de una función muy simple, y las dos maneras de invocarla:

 

La sintaxis de las definiciones de funciones y también de las invocaciones, se pone interesante cuando uno de los parámetros es una función:

 

Hasta aquí estamos manejando funciones de orden superior, usando referencias a métodos y/o funciones. Este ejemplo que puse es particularmente interesante porque se presta para que muchos digan "oye, pero es demasiado verboso tener que definir una función tan simple como lo de evaluar si un número es par/non, en otros lenguajes se puede pasar un closure o una función anónima"; pues bien, en Ceylon ya tenemos también funciones anónimas. La restricción es que una función anónima puede ser solamente una expresión, pero para este ejemplo quedan a la medida (y esta restricción es temporal).

Sólo para reforzar el punto, quiero aclarar que una manera alterna de definir la función   es así:

 

Funciones anónimas

Una función anónima no tiene nombre, y dado que solamente puede contener una expresión, no necesita llaves para definir su cuerpo. Entonces la sintaxis es simplemente  . Entonces podemos implementar lo de par y non como funciones anónimas:

 

Funciones inline

La siguiente pregunta es un poco obvia: ¿Qué pasa si queremos definir una función anónima de varias sentencias? La respuesta, estrictamente hablando, es que no se puede. Pero de manera más práctica, lo que se puede hacer es definir una función inline, lo cual es posible utilizando la sintaxis de argumentos nombrados:

 

En este último caso, estamos definiendo una función para determinar si un número es primo, dentro de la invocación a otra función. La función que definimos en la invocación debe tener el mismo nombre que tiene en la definición de la función que estamos invocando, es decir, dado que el parámetro dentro de la función   se llama  , la función que definimos al invocar   debe llamarse   también.

Funciones parciales

La manera de implementar funciones parciales en Ceylon es simplemente definir múltiples listas de parámetros. Normalmente, un método o función tiene una sola lista de parámetros; cuando se definen dos o más, el compilador crea una nueva función anidada por cada lista de parámetros; la función más interna contiene el código definido originalmente, así como el tipo de dato definido (o inferido), mientras que las demás funciones que la envuelven, devuelven  . Un ejemplo simple puede ser así:

 

Para entender mejor la utilidad de las múltiples listas de parámetros, pondré un ejemplo más práctico. Imaginen una consulta de SQL parametrizada, que se convierte en un PreparedStatement de JDBC. En Ceylon podríamos tener algo así:

 

En invocaciones indirectas, los parámetros secuenciados deben pasarse como un solo argumento de tipo secuencia, es por eso que hay llaves adicionales en las últimas llamadas.

Lo que sigue

Hasta aquí es lo que se tiene implementado en cuanto a funciones, que será incluido en el siguiente release. Pero todavía quedan varias cosas por hacer.

Actualmente hay algunas limitaciones: las funciones anónimas son de una sola expresión, y sólo se pueden usar argumentos nombrados en la primera invocación de una serie de invocaciones concatenadas (cuando la invocación a una función devuelve otra función que es invocada de inmediato). Estas limitaciones son temporales, lo más probable es que se implemente lo necesario para la versión 1.0 o incluso después, ya que hay todavía bastantes otras cosas que implementar como comprehensiones, que ya no debe ser un gran problema ahora que se tiene lo necesario en cuanto a funciones de orden superior para continuar.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de bferro

Buenos avances

Buenos avances. Mis comentarios:

  • Invocar a un Callable de manera directa es un buen feature.
  • No me queda claro eso de que las funciones anónimas están limitadas a un sola expresión y por eso no puede contener varias sentencias. ¿Un bloque no es una expresión?
  • Cuando dices que mediante múltiples listas de argumentos podemos crear funciones parciales, me imagino que lo que quieres decir es aplicación parcial de una función que es algo diferente que las funciones parciales.

Ceylon avanza, que bueno.

@Bferro La limitante entiendo

@Bferro La limitante entiendo es por el estado en el que va la implementación más que a una definición del lenguaje.