En todos los lenguajes hay que trabajar con las decisiones. Las decisiones son el mecanismo por medio del cual un programa hace operaciones dependiendo de situaciones que ocurran durante su ejecución. En ésta entrada voy a describir cómo son las condiciones en Scheme. Disfrútenlo.

En Scheme, casi todas las expresiones siguen una filosofía de reemplazar y ejecutar, es decir, usualmente primero se evalúan los valores de las funciones más internas de una expresión, reemplazando primero las variables por sus valores y luego por el resultado de la operación. Es decir, la filosofía de Scheme es que cada vez que se inicia un paréntesis se llama a una función y si dentro de ella hay más parentesis se evalúan primero esos paréntesis.

Las decisiones por otro lado constituyen lo que en Scheme se llaman formas especiales, ya que no se rijen por la regla de evaluar todas las expresiones interiores para luego ejecutar las exteriores. Hay otra forma especial que se usa con frecuencia y que mis estudiantes de programación ya conocen: define. El define no evalúa sus contenidos como lo haría una expresión ordinaria, por ejemplo una operación matemática como (+ 3 (* 5 6)).

La sintaxis de las decisiones en Scheme es muy simple, la palabra reservada if como si fuera una función más cuyos parámetros son una condición (valor booleano o expresión booleana) y dos expresiones ejecutables. Una forma de resumir la estructura de una decisión es

(if (<condición>) (<expresión-cuando-verdadero>) (<expresión-cuando-falso>) )

Pongo entre <> los contenidos de las expresiones porque pueden ser cualquier cosa, con la condición de que la primera se puede evaluar como true (#t) o false (#f) y las últimas dos sean expresiones ordinarias. If es una forma especial porque contrario a lo que hemos visto, no se evalúan todos los argumentos antes de ejecutar el if, por el contrario, primero se evalúa la condición y si su resultado es verdadero (true) se ejecuta la siguiente expresión y si no se ejecuta la siguiente.

Por ejemplo,

(define (paridad x) (if (odd? x) (‘impar) (‘par)))

La función definida en la línea anterior, devuelve el símbolo ‘impar si x es un número impar (obtenido mediante el operador odd?, que retorna true si su argumento es impar) o ‘par si x no es ‘impar.

Explorando las decisiones

Para hacer las siguientes funciones puede ser útil utilizar las funciones quotient y remainder, antes de continuar, intente descubrir su significado haciendo las siguientes operaciones: (quotient 25 2), (remainder 25 2).

Ejemplo: Hacer una función que determine si un número es divisible por 4

; divisible-4? número -> booleano

(define (divisible-4? x) (= (remainder x 4) 0))

; prueba

(divisible-4? 16)

Explicación: En la función anterior, la operación por la cual se reemplaza una ejecución de divisible-4? es comparar el restante de dividir x por 4, si el restante es 0 entonces el valor es divisible por 4 (verdadero) sino es falso.

Ejemplo: Hacer una función que retorne la hora militar si se le da la hora convencional

(define pm ‘pm)

(define am ‘am)

(define (convencional hora m) (if (= m ‘pm) (+ 12 hora) hora))

Explicación: Primero se definen unos valores simbólicos (el significado es arbitrario y lo da el usuario) para poder escribir pm y que el programa lo pueda usar sin sacar errores. Luego se pregunta si la jornada es pm, si lo es se suma 12 y si no lo es (es am) se devuelve la hora normal. Las 12 del mediodía se escriben 12 m, ¿qué le pasará al programa cuando se escribe éste valor?, ¿qué tipo de error tiene?.

Ejercicios:

  • Hacer la función divisible? que retorne verdadero si el primer argumento es divisible por el segundo y falso en cualquier otro caso.
  • Hacer que divisible? retorne una cadena de error si algún argumento no es un número.
  • Hacer una función llamada entre que retorne verdadero si el primer argumento está entre el segundo y el tercero (incluyendo los límites), por ejemplo (entre 2 1 12) -> true, (entre 15 1 12) –> false
  • Hacer una función que devuelva el valor de la hora convencional si se le da un valor de 0 a 23. Use cadenas para devolver el resultado. Le puede resultar útil el operador number->string.
  • Hacer una función que convierta grados celsius a Fahrenheit pero validando que el valor de Celsius no sea menor a -273 (mínimo absoluto).
  • Con el programa anterior, halle la temperatura mínima en grados Fahrenheit y haga un programa equivalente que convierta de Fahrenheit a Celsius.

Interesante: Una ecuación algebráica, en particular una cuadrática, es una relación entre valores desconocidos, por ejemplo: x^2+2x+1=0, se puede interpretar como una pregunta sobre qué valores de x hacen ésta relación verdadera.

  • Escriba una función que retorne verdadero si se llama con un valor que satisface la ecuación mencionada.
  • Hacer una función que halle una raíz de una ecuación cuadrática, por ejemplo, (raíz- a b c) hallaría la raíz negativa de la ecuación dada por ax^2+bx+c=0 usando la fórmula general -b-b2-4ac2a, por otro lado una función (raíz+ a b c) retornaría la raíz positiva -b+b2-4ac2a
  • Una ecuación cuadrática tiene dos raíces reales, una sólo raíz o no tiene raíces reales, todo depende de si b^2-4ac es mayor, igual o menor que cero. Defina una función que devuelva cuántas raíces reales tiene una ecuación cuadrática dados sus coeficientes a, b y c.