En este artículo veremos funciones (y también procedimientos).
Con esta frase “divide y vencerás”, atribuida a Julio César, los romanos encontraron una estrategia sumamente efectiva para la política y la guerra.
Esta es una idea que también se aplica a la resolución de problemas.
Dado un problema complejo lo dividimos en partes o subproblemas, más simples de resolver.

Una vez encontrada la solución de cada una de las partes, o subproblemas, las combinamos y resolvemos el problema principal.

Llamamos módulo a cada parte, y a todo el proceso, modularización.
Cada módulo resuelve algunos de los subproblemas que conforman el problema original..
La modularización, en programación, consiste en construir un programa a partir de módulos independientes>, y todo esto se puede hacer gracias a las funciones.
Las funciones son bloques de código que realizan tareas específicas.
Dividen tareas grandes en varias tareas más pequeñas, y permite reutilizar lo que ya hicimos, o incluso lo que otros hicieron, en lugar de comenzar de cero.
Vimos algunas funciones, como leer, imprimir, que son funciones básicas brindadas por los propios lenguajes, con las que podemos armar nuestros algoritmos.
Una función tiene la forma:

El nombre de la función, el tipo de dato que retorna y entre paréntesis los parámetros, separados con “,” cada uno con su tipo.
Los parámetros permiten pasar valores a una función para su procesamiento.
Dentro de la función se definen las variables locales, no se ven afuera, y las acciones que ejecuta la función, las instrucciones.
Finalmente retorna el resultado para el invocador.
Hay dos momentos a la hora de pensar en una función:
Los parámetros son variables usadas para meter datos adentro de la función, porque la función no conoce lo que está afuera, solo conoce lo que se declara adentro y los parámetros.
Una función puede no recibir parámetros, en este caso la función se define con el paréntesis vacío.
tipo_retorno nombre_funcion()
Las variables que declaramos dentro de la de la función son locales a la función, fuera de la función no existen.
Hay variables que se declaran por fuera (o con alguna clausula como global, según el lenguaje) son variables globales, se pueden usar en cualquier parte del programa.
En programación se recomienda no usar, o usar lo menos posible variables gl
La práctica es lo que da el criterio de cuándo conviene y cuándo no.
Hay funciones que no retornan valor, en ese caso el tipo retorno es void.
void nombre_funcion (params)
Son llamados procedimientos, se ocupan de alguna tarea pero no retornan nada. Por ejemplo un procedimiento que guarde datos en disco.
Los programas suelen estar formados por un programa principal corto (que también es una función) que lo que hace es invocar a las demás funciones.
Vamos a pensar cómo podemos aplicar la modularización al siguente ejercicio.

Este problema lo podemos dividir en módulos: un problema principal dividido en subproblemas más fáciles de resolver.
Por un lado podemos hacer la lectura del radio, por otro lado el cálculo del perímetro, por otro el cálculo del área y por otro lado la visualización de resultados.

De esta forma nos queda el problema dividido en módulos, modularizado.

Nos pide que usemos una función suma, que va a sumar dos números enteros y retornar el resultado de la suma.
Vamos a tener que pasarle dos parámetros a la función: num1 y num2.
Dentro de la función podemos usar una variable para guardar el resultado de la suma, la llamamos resultado, es el valor de retorno de la función.

Falta armar el programa principal, carga los datos, invoca a la función suma e imprime el resultado.


Algo importante, esta función suma la podemos reutilizar en cualquier otro programa, no hace falta volver a escribirla..

Van a ingresar 3 notas, con esos 3 datos tenemos que mostrar 3 resultados.
Podemos considerar 3 variables para las notas:
Pueden ser números con coma, variables de tipo decimal.
Vamos a tener 3 variables para los resultados, también de tipo decimal.
Vamos a tener que hacer tres cálculos.
Busquemos patrones, pensemos cómo se hace en cada caso..

Vamos a aplicar un poco de matemática
¿qué pasa cuando multiplicamos un número por 1? ¡Obtenemos el mismo número!
Entonces si hacemos;
Podemos decir que el promedio normal es equivalente tener un peso de ponderación 1 en cada nota.
promedio normal = PESO * 1
Podemos escribir el último caso de otra manera:
Promedio = (Nota1 * 1 + Nota2 * 1 + Nota3 * 1) / 3
Ahora, miremos bien, hay cosas parecidas:

Tenemos nota1 multiplicando un número, el peso de la nota 1 (pesoNota1) sumado a nota2 multiplicado por el peso de la nota 2 (pesoNota2) y eso sumado a nota3 multiplicando por el peso de la nota 3 (pesoNota3).
Esto nos dice que podemos armar una fórmula genérica, en donde cambiando el peso de la nota nos va a dar cada resultado particular.
Con la fórmula genérica ahora podemos crear una función que retorne el resultado de esta fórmula, el promedio ponderado, para las notas y pesos que le pasemos por parámetro.
La podemos llamar funciónPromedioPonderado, va a retornar un número de tipo decimal y como parámetros va a tener:
Declaramos una variable local resultado, va a guardar el resultado y lo retornará al invocador.
Hacemos el cálculo y lo asignamos a esta variable resultado.
Finalmente retorna el resultado.

Teniendo la función de cálculo, queda armar la función principal, que va cargar las notas, invocar a esta función y mostrar los resultados.
Declaramos las variables que habíamos visto, leemos las tres notas. A las variables del promedio les asignamos el resultado de la función del promedio ponderado. Pasamos los parámetros para cada uno y finalmente imprimimos los tres resultados.

Usamos la misma función para los tres casos, solo cambiaron los valores de los parámetros. No tuvimos que escribir tres veces el cálculo, lo escribimos una sola vez. Esto hace que sea menos propenso a errores. si falla el cálculo tenemos que tocar en un solo lugar.
Todavía nos queda algo al hablar de funciones, vamos a ver un caso.

Tenemos el procedimiento suma, que recibe 3 enteros. Al parámetro num3 le asigna la suma de los otros 2.
Al procedimiento lo invocamos desde el programa principal, que ya están inicializadas.
La pregunta es ¿qué valor imprime?
Antes de responder, hablemos de pasaje de parámetros.
Existen dos tipos de pasaje por parámetros, el pasaje por valor y el pasaje por referencia.
Esto se aclara en la definición de la función, vamos a considerar que todo los pasajes son por valor a menos que se indique explícitamente que se trata de un pasaje por referencia, con la cláusula REF
VOID suma (ENTERO num1, ENTERO num2, ENTERO num3)
VOID suma (ENTERO num1, ENTERO num2, REF ENTERO num3)
Lo que sucede con la variable dentro del procedimiento no afecta a la variable original, no le cambia el valor. .
Desde el punto de vista de algoritmos paso el valor que tiene la caja (la variable) y la función trabaja con ese valor.

Desde el punto de vista de la programación el procedimiento hace una copia de la variable y trabaja con esa copia, por lo que no modifica el valor de la variable original.
En este caso, lo que pasa en el procedimiento afecta al valor original de la variable, desde el punto de vista de algoritmos paso la caja directamente.

Desde el punto de vista de la programación, vimos que una variable es una posición de memoria en la que se guarda el valor, en ese caso pasa la dirección de memoria para que pueda cambiar su contenido.
Si la función suma es:

Se trata de un pasaje por valor así que imprime 10.
En cambio si la función suma es:

Se trata de un pasaje por referencia de la variable num3, cambia el valor dentro de la función y se ve reflejado afuera, así que imprime 3.
¿Desde una función se puede invocar a otra función?
Claro que sí, incluso podemos invocar funciones de bibliotecas o librerías.
Una biblioteca es un conjunto de funciones agrupadas que resuelven problemas comunes.
Hay bibliotecas de matemática, que agrupan un montón de funciones como potencia, coseno, logaritmo. Alcanza con incluirlas a las librerías de nuestro código para poder utilizarlas, invocando directamente a la función que necesitamos.
Puede que con los ejemplos con pocas líneas de código que vimos no hayas notado sus beneficios, pero en programas grandes con miles de líneas de código las funciones son fundamentales.
Pero antes, como la única manera de aprender es practicando, aca te dejo unos ejercicios para que practiques y puedas poner en práctica lo que viste:
DECIMAL conversor (PALABRA moneda, DECIMAL cantidad)
INICIO
DECIMAL tasaConversion
SI (moneda == "libra") ENTONCES
tasaConversion = 1.22
SINO SI (moneda == "dolar") ENTONCES
tasaConversion = 0.75
SINO SI (moneda == "yen") ENTONCES
tasaConversion = 0.009
SINO
INICIO
IMPRIMIR "Moneda no válida"
RETORNA -1
FIN
RETORNA cantidad * tasaConversion
FIN
//Programa principal
INICIO
PALABRA moneda
DECIMAL cantidad
DECIMAL resultado
IMPRIMIR "Ingrese la moneda (libra, dolar, yen):"
LEER moneda
IMPRIMIR "Ingrese la cantidad:"
LEER cantidad
// Llamamos a la función para realizar la conversión
resultado = conversor(moneda, cantidad)
// ValidaMOS y mostrar el resultado
SI (resultado != -1) ENTONCES
IMPRIMIR "El equivalente en euros es: " + resultado
FIN
FIN
DECIMAL calcularJornal (ENTERO horasTrabajadas, PALABRA turno, PALABRA dia)
INICIO
DECIMAL tarifaBase
DECIMAL incremento
DECIMAL tarifaFinal
// Determinar la tarifa base según el turno
SI (turno == "nocturno") ENTONCES
INICIO
tarifaBase = 12
incremento = 0.15 // Incremento en fin de semana
FIN
SINO //turno == "diurno"
INICIO
tarifaBase = 10
incremento = 0.10 // Incremento en fin de semana
FIN
// Ajustar tarifa para fines de semana
SI (dia == "sabado" O dia == "domingo") ENTONCES
tarifaFinal = tarifaBase + (tarifaBase * incremento)
SINO
tarifaFinal = tarifaBase
FIN
// Calcular y retornar el jornal diario
RETORNA horasTrabajadas * tarifaFinal
FIN
// Programa principal
INICIO
ENTERO horasTrabajadas
PALABRA turno
PALABRA dia
DECIMAL resultado
IMPRIMIR "Ingrese el número de horas trabajadas:"
LEER horasTrabajadas
IMPRIMIR "Ingrese el turno (diurno, nocturno):"
LEER turno
IMPRIMIR "Ingrese el día de la semana:"
LEER dia
// Llamamos a la función para calcular el jornal
resultado = calcularJornal(horasTrabajadas, turno, dia)
// Resultado
IMPRIMIR "El jornal diario es: " + resultado + " €"
FIN
El el siguiente artículo veremos Arrays, una variable que puede almacenar más de un valor, un conjunto de valores.