Skip to content

Instantly share code, notes, and snippets.

@alcidesfp
Created September 25, 2012 17:02
Show Gist options
  • Save alcidesfp/3783163 to your computer and use it in GitHub Desktop.
Save alcidesfp/3783163 to your computer and use it in GitHub Desktop.
Programa mascota simple en Scheme Chicken
#!/usr/local/bin/csi -s
;; -*- coding:utf-8; mode:Scheme -*-
(use extras)
(define (pide-nombre)
(display "Hola, ¿Cuál es tu nombre?: ")
(read-line))
(define (pide-ann)
(display "¿En qué año naciste?: ")
(string->number (read-line)))
(define (calcula-edad ann-nac #!optional (ann-actual 2012))
(if ann-nac (- ann-actual ann-nac) 0 ))
(begin
(display "¡Hola a todos desde Scheme!\n")
(let* ((nombre (pide-nombre))
(edad (calcula-edad (pide-ann))))
(format #t "Hola ~a.~%" nombre)
(format #t "En el año ~a tendrás ~a años.~%" 2012 edad)))
@yngwie74
Copy link

Bueno, aquí voy a demostrar lo mucho que ignoro sobre scheme:

  • En la linea 14, no sé si en verdad esta validación "defensiva" va aquí o debería ser parte de pide-ann.
  • Fuera de la documentación que proporciona por su mera existencia, el begin cumple con alguna otra función?
  • No me queda claro cómo se pueden "inyectar" valores al programa si es que no quieres usar la entrada por teclado (p.e. una prueba unitaria)

Lo que si me llama poderosamente la atención es la manera en que al eliminar los set's se encuentran puntos de sección naturales en el código. Habría que intentarlo en algo más "sofisticado" (er.. complejo) para ver qué sucede. Tal vez descubriste un principio más general de lo que el gist deja ver.

@alcidesfp
Copy link
Author

Estimado Alfred: Tres meses después, irónicamente, debido a la terrible gripa que me ha aquejado antes, durante y después de Navidad, por fin tengo tiempo para responder los comentarios que me haces favor de expresar por este medio:

  • La validación a la que te refieres en la línea 14 es la solución mas simple. Se basa en el hecho de que la función string->number regresa #f si el argumento no es convertible o es nulo. De otra manera las funciones pide-ann y calcula-edad quedarían como sigue:
(define (pide-ann)
  (display "¿En que año naciste?:")
  (let ((ann (string->number (read-line)) ))
    (if (not ann) 0 ann) ))

(define (calcula-edad ann-nac #!optional (ann-actual 2012))
  (if (= 0 ann-nac) 0 (- ann-actual ann-nac)) )

En este caso es solamente una línea mas de código, pero ya nos sugiere la necesidad de una prueba unitaria y la consiguiente refactorización (rangos permitidos, valores a considerar, criterios de error, etc) La cual ya es posible sin mayores esfuerzos teniendo el código escrito de esta forma.

(cond-expand (chicken (use srfi-64))
             (kawa (require 'srfi-64)))
(define pruebas ;;Lista de valores de pruebas
  '((ann1 edad1)
    (ann2 edad2)
    (ann3 edad3)
    (ann4 edad4))) 
(test-begin "prueba-calcula-edad")
(for-each 
  (lambda (elem) 
    (let* ((arg (car elem)) (act-val (cadr elem)) (exp-val (calcula-edad arg)))
      (test-equal exp-val act-val))) pruebas)
(test-end)
  • La forma begin es la manera natural en Scheme de agrupar en un bloque de código varias expresiones para su evaluación secuencial (el equivalente a PROGN de Common-Lisp). En mi caso, la utilizo como una convención estilística de agrupación de las expresiones del programa principal, la cual me permite su rápida evaluación, activar/desactivar su ejecución o bien renombrarlas/moverlas a otra función de un solo teclazo.
  • Las funciones pide-nombre y pide-ann esencialmente no hacen nada mas que llamar a las funciones de la biblioteca estándar de Scheme (display, readline, string->number, etc) y son realmente parte de la interfaz de usuario (IU) (CLI en este caso) por lo cual no les he asignado ninguna responsabilidad adicional y por lo tanto están fuera del alcance de las pruebas aquí consideradas. No está dentro de mi alcance inmediato hacer pruebas de caracterización para las bibliotecas de Scheme. Aunque con el código ya desacoplado de la UI, no dudo que se puedan hacer pruebas con una interfaz de usuario mas compleja (Kawa / Swing).

Sin mas por el momento, me despido de ti, enviándote un cordial saludo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment