La composición de funciones consiste en usar funciones para obtener un resultado dentro de otra función. En el libro How to design programs, se describe en el capítulo 3 un interesante ejemplo de composición que voy a describir a continuación. Disfrútenlo.

Como decía en la introducción, la composición consiste en usar funciones intermedias para lograr un objetivo. Por ejemplo, si quisiera obtener el valor absoluto de un valor numérico mediante su definición matemática |x|=raíz cuadrada de x al cuadrado, pero en el mismo programa quisiera hallar la longitud de una hipotenusa dados los catetos (raíz cuadrada de la suma de sus catetos al cuadrado), probablemente quiera definir una función llamada cuadrado que eleve un valor a su segunda potencia.

(define (cuadrado x) (* x x))

Con ésta definición intermedia, ahora la definición de las otras dos funciones sería más entendible e incluso más breve.

(define (hipotenusa c1 c2) (sqrt (+ (cuadrado c1) (cuadrado c2))))

(define (absoluto-de x) (sqrt (cuadrado x)))

Existen otras formas de composición, por ejemplo, si yo definiera una función que promedia dos valores, podría reusarla para promediar cuatro de la siguiente manera:

(define (promedio a b) (/ (+ a b) 2))

(promedio (promedio 1 2) (promedio 3 4))

equivalente a la operación (/ (+ 1 2 3 4) 4)

Existen varias formas de hacer lo anterior de maneras más eficientes, pero éstos ejemplos simples permiten ilustrar la composición sin mayores problemas.

Una de las razones de hacer composición de funciones es convertir problemas complejos en partes más simples, de tal manera que sea más fácil resolver el problema completo atacando partes más fáciles de resolver y luego estableciendo las relaciones entre las partes pequeñas. Otra razón es la posibilidad de reusar procedimientos que siempre hagan lo mismo de manera confiable y comprensible.

Ejemplo del teatro

Lea atentamente la siguiente situación. El propietario de un teatro desea hacer un programa que calcule las ganancias obtenidas en cada presentación. Un cliente paga $10.000 por entrada, cada función le cuesta al teatro $300.000 por la atención prestada en la sala (proyectista, luces, acomodación, etc. ) y por cada cliente que entre, el teatro debe pagar un costo de $2.000 por aseo. Desarrolle un programa que reciba el número de clientes de una función y devuelva el valor de las utilidades obtenidas. Considere las siguientes relaciones:

  • utilidad es la diferencia entre costos y ventas
  • ventas es el valor neto recaudado por todos los tiquetes (o entradas)
  • costos son los valores invertidos en cada función (costo fijo y costo variable)

Si cada uno de los elementos anteriores son funciones, ¿de qué dependerían las funciones anteriores?, es decir, ¿cuáles son sus parámetros?. Desarrolle cada uno de ellos para encontrar la utilidad de una función cualquiera según la cantidad de entradas vendidas.

Mayor nivel de dificultad

Tomando como base el caso del ejemplo anterior, se descubrió que con entradas a $10000 entran 120 personas, pero por cada disminución de $500 en la entrada, aumenta la asistencia en 15 personas más. Por lo tanto, si entran más personas aumenta la utilidad pero se gana menos por cada cliente, es decir, hay que bajar la utilidad por entrada para aumentar la asistencia pero si aumentamos la asistencia se gana más, pero ¿hasta cuánto podemos bajar las entradas?.  Reescriba el programa para descubrir ¿qué valor deberían tener los tiquetes para obtener la mejor utilidad?

Nota: Probablemente prefiera redefinir las funciones anteriores como dependientes del precio de la entrada.

Para terminar, el problema en sí mismo se puede resolver de otras maneras probablemente con más eficiencia, por ejemplo, se puede escribir una ecuación completa en términos del valor de la entrada y mediante derivadas encontrar el valor mínimo entre otras soluciones, pero la actual es una forma fácil de hacer prueba y error con un programa que usa composición de funciones.