◯ Scheme — 1975

⬅️ Atlas · 🗂️ Todas las fichas · 📚 Índice de clases

Scheme es el Lisp minimalista: su especificación completa cabe en unas cincuenta páginas, frente a las mil de Common Lisp. Fue durante décadas el lenguaje con el que se enseñaba a programar en el MIT, y de él salieron las continuaciones, la recursión de cola garantizada y las macros higiénicas.

🎯 Por qué está en este programa

Scheme es un primo de la familia Lisp (Atlas), que no tiene representante en el núcleo — Common Lisp y AutoLISP son sus parientes entre los lenguajes vivos.

Aporta al programa tres conceptos concretos: las continuaciones de primera clase (clase 127), la recursión de cola garantizada por el estándar (clase 083) y las macros higiénicas (clase 122). Y aporta la demostración de que un lenguaje puede ser minúsculo y completo a la vez.

Año 1975; R5RS (1998) el más querido; R7RS (2013) el vigente
Autoría Guy L. Steele y Gerald Jay Sussman, MIT
Familia Lisp; con el alcance léxico del cálculo lambda de Church
Paradigma Multiparadigma con base funcional; sin imponer nada
Tipado Dinámico y fuerte; numéricos exactos y con torre de tipos
Memoria Recolección de basura
Ejecución Depende de la implementación: intérprete, bytecode o nativo
Estado 🟢 Vivo: enseñanza, investigación y Guile como lenguaje de extensión de GNU

📜 Historia

En 1975, Steele y Sussman en el MIT escribieron un intérprete pequeño para estudiar el modelo de actores de Carl Hewitt. Y descubrieron algo que cambió el diseño de lenguajes: al implementar los actores con cierres léxicos, actores y funciones resultaban ser lo mismo.

De ahí salieron los Lambda Papers —una serie de informes con títulos como Lambda: The Ultimate Imperative— que demostraron que con lambdas y alcance léxico se pueden construir todas las estructuras de control: bucles, condicionales, excepciones y saltos.

Y de ahí las decisiones de Scheme:

SICP —Structure and Interpretation of Computer Programs, de Abelson y Sussman, 1985— usó Scheme para enseñar programación en el MIT durante veinte años, y es probablemente el libro de informática más influyente jamás escrito. Está libre en línea.

Y R6RS (2007) provocó la única crisis del lenguaje: era grande y prescriptivo, la comunidad se dividió, y R7RS (2013) volvió al minimalismo con un núcleo pequeño y módulos opcionales.

🏭 Dónde vive hoy

🧠 Lo que enseña: continuaciones y recursión de cola

Uno, call/cc —capturar la continuación—, que es la construcción de control más potente que existe (clase 127):

(define (buscar lista objetivo)
  (call/cc
    (lambda (salir)                     ; ← 'salir' ES el resto del cálculo
      (for-each (lambda (x)
                  (if (equal? x objetivo) (salir #t)))
                lista)
      #f)))

call/cc da como valor "todo lo que falta por hacer", y llamarlo salta ahí. Con eso se pueden construir —dentro del lenguaje, sin sintaxis nueva— excepciones, generadores, corrutinas, hilos cooperativos y vuelta atrás.

Es la demostración más pura de la tesis de los Lambda Papers, y es la razón de que Seaside pudiera hacer aplicaciones web con continuaciones (clase 168).

Dos, la recursión de cola garantizada:

(define (contar n acc)
  (if (= n 0) acc (contar (- n 1) (+ acc 1))))   ; ← NO crece la pila
(contar 10000000 0)                               ; funciona

El estándar obliga a que una llamada en posición de cola no consuma pila (clase 083). Eso hace que el bucle y la recursión sean lo mismo, y por eso Scheme no necesita for ni while.

Y tres, las macros higiénicas:

(define-syntax mi-si
  (syntax-rules ()
    ((_ c t e) (cond (c t) (else e)))))

"Higiénicas" significa que las variables de la macro no capturan las de quien la usa —el problema clásico de las macros de Common Lisp y del preprocesador de C (clase 123)—. Scheme lo resolvió con syntax-rules, y es la solución que después adoptaron Rust y Racket.

🔄 Lo que se ha modernizado

⚙️ Cómo se ejecuta hoy

guile main.scm < entrada.txt          # GNU Guile
chez --script main.scm                 # Chez Scheme, muy rápido
csi -s main.scm                         # Chicken Scheme (compila a C)

🧪 El programa de la clase 041 en Scheme

Esta versión se escribe aquí y no está verificada en CI (clase 040).

(use-modules (ice-9 rdelim))

(let* ((linea   (read-line))
       (campos  (string-split linea #\space))
       (nums    (map string->number campos))
       (total   (* (car nums) (cadr nums) (- 1 (caddr nums)))))
  (format #t "Total: ~,2f~%" total))

Lo que hay que ver.

📚 Fuentes y bibliografía


⏮️ Volver al Atlas · 🗂️ Todas las fichas · 🔗 Relacionadas: Common Lisp · Racket · Clojure · Emacs Lisp · AutoLISP