📝 Emacs Lisp — 1985

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

Emacs Lisp es, probablemente, el lenguaje incrustado con más código escrito de la historia — y el único cuyo anfitrión es tan indistinguible de él que la pregunta "¿Emacs es un editor o un intérprete de Lisp?" tiene una respuesta clara: es un intérprete de Lisp que resulta que edita texto.

🎯 Por qué está en este programa

Emacs Lisp es un primo de la familia Lisp (Atlas).

Aporta al programa el caso de estudio más grande y más antiguo de incrustar un lenguaje en otro: cuarenta años de una aplicación cuyo 90 % está escrito en su propio lenguaje de extensión, modificable en marcha. Y es el último lugar de uso masivo donde sobrevive el alcance dinámico (clase 088), que aquí se puede estudiar en vivo.

Año 1985 (GNU Emacs 13); Emacs es de 1976, con otro lenguaje
Autoría Richard Stallman, sobre el Emacs original de Stallman y Guy Steele
Familia Lisp; más cerca de MacLisp que de Scheme o Common Lisp
Paradigma Imperativo y funcional; orientado a objetos con EIEIO
Tipado Dinámico; con alcance dinámico por defecto hasta hace poco
Memoria Recolección de basura
Ejecución Bytecode interpretado; compilación nativa a C desde Emacs 28
Estado 🟢 Muy vivo dentro de su ecosistema; irrelevante fuera

📜 Historia

Emacs nació en 1976 en el MIT como un conjunto de macros para el editor TECO —de ahí el nombre, Editor MACroS—. Cuando Richard Stallman arrancó el proyecto GNU en 1984, reescribió Emacs desde cero y tomó una decisión que lo definió todo: el editor tendría un intérprete de Lisp dentro, y todo lo que no fuera imprescindible se escribiría en Lisp.

El resultado es una arquitectura de dos capas exacta a la que Ousterhout describiría trece años después (clase 155):

Un núcleo en C:  el intérprete de Lisp, la gestión de búferes, el dibujado
                  y las primitivas de bajo nivel.

Todo lo demás en Emacs Lisp:  los modos de edición, el cliente de correo,
                               la interfaz de git, el gestor de ficheros,
                               el depurador, el calendario, el organizador…

Y con una propiedad que ningún otro sistema de esta lista tiene igual: todo eso es modificable en marcha, sin reiniciar y sin recompilar (clase 124).

Org mode —un sistema de notas, tareas, agenda y documentos reproducibles— es, por sí solo, uno de los programas Lisp más grandes que existen, y está escrito íntegramente en Emacs Lisp por gente que no es programadora de lenguajes.

Y en 2021, Emacs 28 trajo el cambio más importante en décadas: compilación nativa. Emacs Lisp se traduce a C y se compila con GCC, con mejoras de rendimiento de varias veces.

🏭 Dónde vive hoy

🧠 Lo que enseña: el alcance dinámico, en vivo

Emacs Lisp es el último sitio de uso masivo donde el alcance dinámico es el comportamiento por defecto, y eso lo hace un laboratorio perfecto para la clase 088:

(defvar *nivel* 0)                     ; variable especial: alcance DINÁMICO

(defun escribir (msg)
  (message "%s%s" (make-string *nivel* ?\s) msg))

(defun con-sangria (f)
  (let ((*nivel* (+ *nivel* 2)))       ; ← afecta a TODO lo que se llame desde aquí
    (funcall f)))

let sobre una variable especial no crea una variable local: cambia temporalmente la global, y todo lo que se ejecute dentro —incluidas funciones que no sabían nada de esto— ve el valor nuevo.

Y en un editor eso resulta ser exactamente lo que hace falta: case-fold-search, default-directory, inhibit-read-only son variables que se enlazan alrededor de una operación para cambiar cómo se comporta todo el código que participa.

Es la razón por la que Emacs Lisp lo conservó cuando el resto del mundo Lisp se pasó al alcance léxico — y desde Emacs 24 se puede activar el léxico por fichero, que es hoy la recomendación:

;;; -*- lexical-binding: t -*-

Y hay una segunda cosa que Emacs enseña, y es de la clase 163: el anfitrión y el lenguaje incrustado casi no tienen frontera.

(defun mi-comando ()
  (interactive)                        ; ← esto lo convierte en un comando invocable
  (insert (format-time-string "%Y-%m-%d")))

(global-set-key (kbd "C-c d") #'mi-comando)

No hay API que registrar ni puente que cruzar: las funciones del editor son funciones Lisp, y las funciones propias son comandos del editor. Es el extremo opuesto de los alias de Safe-Tcl, donde la frontera está cerrada a propósito (clase 153).

Y el precio es el que la clase 163 advierte: no hay aislamiento. Un paquete de MELPA puede hacer cualquier cosa, y la seguridad depende por completo de la confianza en quien lo escribió.

🔄 Lo que se ha modernizado

⚙️ Cómo se ejecuta hoy

emacs --batch -l main.el                   # ejecutar un guion sin interfaz
emacs --batch -f batch-byte-compile *.el    # compilar a bytecode
emacs --batch -l ert -f ert-run-tests-batch-and-exit   # pruebas (clase 139)

# Y dentro de Emacs: C-x C-e evalúa la expresión anterior, EN EL SISTEMA VIVO

🧪 El programa de la clase 041 en Emacs Lisp

Emacs Lisp puede ejecutarse en lote, aunque no sea su uso natural. No está verificado en CI (clase 040).

;;; -*- lexical-binding: t -*-
(let* ((linea (read-string ""))
       (campos (split-string linea))
       (nums (mapcar #'string-to-number campos))
       (total (* (nth 0 nums) (nth 1 nums) (- 1 (nth 2 nums)))))
  (princ (format "Total: %.2f\n" total)))

Lo que hay que ver.

📚 Fuentes y bibliografía


⏮️ Volver al Atlas · 🗂️ Todas las fichas · 🔗 Relacionadas: Common Lisp · Scheme · AutoLISP · Tcl · Lua