Qué son las funciones, para qué nos sirven las funciones y cómo las definimos en los lenguajes de programación. Algunos ejemplos sobre implementación de funciones y su invocación.
En el capítulo anterior del Manual de Iniciación a la programación quisimos presentar un concepto como la Programación estructurada, que es un paradigma de la programación. Era interesante aborarlo para que supiésemos de dónde salen las funciones y por qué son tan relevantes en la evolución de la programación. Sería ideal que lo leas para poder entender bien el contexto en el que aparecen las funciones y sus ventajas.
Ahora vamos a abordar las funciones desde un punto de vista más práctico, viendo algunos ejemplos de ellas, de modo que podamos entender mejor qué son, cómo se definen y cómo se invocan.
Aclaramos, no obstante, que el objetivo de este artículo no es que te conviertas en un experto programador de funciones, eso ya llegará con el tiempo!! simplemente queremos que sepas en qué consiste, cuál es su utilidad, cómo se construyen y qué partes tienen.
Qué son las funciones
Las funciones, también conocidas como subrutinas o procedimientos, son bloques de código a los que se les asigna un nombre. Dentro del bloque de código de una función podemos encontrar lo mismo que encontramos en un algoritmo común, es decir, sentencias secuenciales, estructuras condicionales y estructuras de repetición.
Mediante el nombre con el que hemos etiquetado a la función podemos más adelante invocarla, todas las veces que sea necesario, de modo que se ejecutará el bloque de sentencias que contiene.
Puedes entender a las funciones como un pedazo de código con una o muchas sentencias que has apartado a un lado, le has puesto un nombre y puedes recurrir a él cada vez que lo necesitas ejecutar.
Para qué sirven las funciones
Si has conseguido entender qué es una función, aunque todavía de una manera únicamente conceptual, podrás deducir que la ventaja más importante de una función (aparentemente) es que la puedes invocar todas las veces que necesites, de modo que convendrás conmigo que permite la reutilización de un código. Incluso, una vez que escribes un código dentro de una función, te lo podrías llevar a muchos otros programas para poder reutilizarlo de manera recurrente a lo largo de muchas aplicaciones.
Por ejemplo, creas una función que solicita un número al usuario, que por supuesto se encarga de solicitar repetidas veces ese número hasta que el usuario nos entrega verdaderamente un valor numérico y no cualquier otra cosa. Esa utilidad, bastante típica, la podrás usar en muchos programas distintos.
Pues bien, aunque es innegable que las funciones permiten la reutilización del código, lo cierto es que sus ventajas más importantes van mucho más allá.
Las mayores ventajas de las funciones las encontramos en su capacidad para organizar el código de las aplicaciones. Si tienes que hacer algo muy tonto y muy básico quizás no tengas problemas para conseguir programarlo de cualquier manera, pero imagínate tener que hacer algo como un juego, un procesador de textos o cosas sencillas pero que ocupen más de 100 líneas de código. Si no te organizas, será muy difícil conseguirlas de una manera ordenada y fácilmente mantenible.
Gracias a las funciones conseguimos:
- Una estructura para nuestro programa
- La capacidad de abstraernos sobre cómo está escrita esa función por dentro, simplemente sabemos que hace su labor y la hace bien
- La capacidad de encapsular datos dentro, que pertenecen a la función y que nadie los puede manipular desde fuera.
Hemos sacado otro concepto esencial de programación a la palestra: encapsulación. En el anterior artículo dedicado a la programación estructurada ya mencionamos qué era la abstracción. Pues bien, la encapsulación es el proceso por el que se oculta deliberadamente características de una abstracción. No solo es que, mediante la abstracción puedas despreocuparte sobre cómo está hecha una función, sino que además voy a encapsular ciertos datos de una función para que no los puedas tocar desde fuera, lo que evita impactar a todas las personas que usan una función cuando la implementación de ésta cambie. Ambos conceptos, tanto abstracción como encapsulación los encontramos ya en las funciones, pero son todavía más patentes en la programación orientada a objetos, pero ya existen en la programación estructurada. Por cierto, la encapsulación de las funciones se da mediante la creación de variables locales a las funciones, que son variables que desde fuera de la función nadie podrá mencionar, porque solamente se conocen dentro del código de la función.
Cómo definir una función
No es común ver diagramas de flujo o pseudocódigo que definan la estructura completa de una aplicación con su jerarquía de funciones, sino más bien para expresar algoritmos sueltos. A nivel de aplicación se utilizan otro tipo de diagramas comúnmente. Por ello voy a escribir una función directamente con código Javascript para que se pueda apreciar qué partes tiene una función.
Generalmente cuando diagramas un algoritmo te quedas en la secuencia de acciones para resolver un problema. Podrías diagramar el flujo de ejecución de un proceso y luego meterlo dentro de una función. A decir verdad los diagramas de flujo tienen un símbolo para el proceso, que podrías usar para decir que ahí va el código de un algoritmo que hemos separado a una función, pero ya advierto que no estoy muy al día en estos diagramas de flujo. Básicamente señalo este punto porque hasta ahora en el manual de iniciación a la programación se estaba viendo todo con diagramas y pseudocódigo y quiero justificar el paso a usar directamente código fuente real. En cualquier caso, personalmente tampoco uso habitualmente diagramas de flujo o pseudocódigo para la definición de algoritmos, ya que hace mucho que pasé la etapa de aprendizaje de la programación. Seguramente tú tampoco lo necesites de aquí a poco.
En Javascript, y en muchos otros lenguajes, una función se define con la palabra "function" seguida del nombre de la función. A continuación se ponen unos paréntesis y luego abrimos llaves y cerramos llaves. Dentro de las llaves colocamos el código que pertenece a esa función, es decir, la estructura secuencial de instrucciones, con las estructuras como condicionales o ciclos que has aprendido.
El nombre de la función es un identificador que tiene las mismas reglas de creación que los identificadores que ponemos a las variables.
function nombreDeLaFuncion() {
// código de la funcion
}
Por si no se ha explicado, en el código anterior, la línea que empieza por "//" es un comentario. Los comentarios no se ejecutan al ejecutarse el programa. Simplemente son mensajes que nos dejamos a nosotros mismos, u otros desarrolladores, para cuando lean ese código. Esta función, como no tiene más código dentro de las llaves que un comentario, no haría nada. Es solo para ver su estructura.
Cómo invocar una función
Una vez que tenemos esta función definida en el programa probablemente la querramos invocar, para lo que usamos el propio nombre de la función y los paréntesis de apertura y cierre.
nombreDeLaFuncion() // eso invoca la función, con lo que se ejecutará el código que tenga dentro.
Al invocar la función, el flujo de ejecución del programa se mete dentro de las llaves de la función y comienza a procesar todo ese código, realizando las acciones o cálculos que se hayan programado dentro.
Parámetros de las funciones
Las funciones a veces necesitan recibir datos para poder ejecutarse. Por ejemplo, una función que comprueba si una variable de cadena es una dirección de email bien formada, requeriría recibir por parámetro el email que debe validar.
Las funciones pueden recibir cualquier número de parámetros y se colocna entre los paréntesis en la definición de la función.
function validarEmail(email) {
// Aquí realizaríamos las acciones necesarias para verificar si un email es válido o no
}
En este caso, entre paréntesis hemos colocado "email". Ese es el parámetro de la función. Dentro de la función se conocerá ese identificador "email" que contendrá la dirección que se debe validar.
Al invocar a la función tenemos que enviar los argumentos con datos que necesitan para trabajar.
validarEmail("miguel@desarrolloweb.com");
Otro ejemplo, podemos tener una función que suma dos valores, lo que haría que necesitemos enviarle esos dos datos.
Valores de retorno en funciones
Además, las funciones son capaces de devolver valores. En el caso de la función "sumar", necesitaría devolver el resultado de la operación, para lo que se usa la palabra "return".
function sumar(valor1, valor2) {
return valor1 + valor2
}
No es necesario que las funciones devuelvan siempre valores. Podrían existir perfectamente funciones que no devuelven datos y simplemente realizan algún comportamiento determinado.
Ahora para invocar la función tendremos que enviarle los argumentos de los dos parámetros que ha definido, entre los paréntesis.
let resultado = sumar(4, 6);
Con "let" en Javascript se declara una variable, en este caso "resultado". A esa variable le estamos asignando el valor que nos devuelve la función sumar. Obviamente, hacer una función para algo tan elemental como una suma no tiene mucho sentido, pero lo importante es ver cómo conseguimos declarar una función.
Argumentos vs parámetros
En este punto y para aclarar posibles dudas con respecto a los conceptos que estamos manejando, quiero mencionar la diferencia entre argumentos y parámetros, ya que es algo que probablemente leas por ahí y, aunque parezcan la misma cosa, no lo son.
Los argumentos son los valores que enviamos a una función cuando la invocamos. Por ejemplo, en el siguiente código:
sumar(4, 10)
Los argumentos en la invocación de la función son 4 y 10.
Sin embargo, cuando estamos definiendo una función, los datos que recibimos en ella los llamamos parámetros. La función sumar recibe dos parámetros que se supone que serán los dos números que se tienen que sumar. En cada invocación a la función los parámetros toman los valores de los argumentos usados al invocarla.
Ejemplo de función que calcula si es mayor de edad
Las funciones pueden hacer todo lo que necesites y devolver datos de cualquier tipo que sea necesario. Vamos a ver un segundo ejemplo de función que devuelve si una edad indica o no mayoría de edad.
function esMayorDeEdad(edad) {
if(edad > 18) {
return true;
} else {
return false;
}
}
Para quien use esa función le devolverá un valor boleano true
o false
, indicando con true
que era mayor de edad y con false
que no lo era.
let mayoría = esMayorDeEdad(21);
Al ejecutarse esa línea, la variable mayoria
contendrá el valor true
.
Para acabar, quiero que examines de manera crítica la implementación de la función. ¿Cómo la ves? Quizás más de un lector haya percibido que esta función podría haberse expresado de una manera más sencilla. De hecho podría haber varias mejoras. Si lo has podido analizar, ¡enhorabuena! Si no lo viste de antemano, revisa el siguiente código que es perfectamente equivalente:
function esMayorDeEdad(edad) {
return edad > 18
}
Conclusión
Hay mucho que ver sobre funciones en los lenguajes de programación y por supuesto lo importante es definirlas y usarlas en nuestros propios programas y aprender por la práctica. Cada lenguaje de programación tiene una sintaxis específica para definir funciones, que tendrás que conocer a su debido momento. El objetivo de este artículo era explicar de manera general qué era una función y cuál es el cometido de éstas a la hora de desarrollar aplicaciones.
Poco a poco cuando aprendas lenguajes podrás prácticar más. De momento, si quieres más ejemplos de funciones te recomiendo que leas el Manual de Javascript, que tiene una serie de artículos más detallados dedicados a las funciones. En el siguiente artículo vamos a abordar una técnica de resolución de algoritmos que usa las funciones y se llama recursividad.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...