Haskell por fin tiene debugger DAP. El fin de una excusa de 20 anos.
La noticia
https://well-typed.github.io/haskell-debugger/
Well-Typed (los maintainers de GHC, los que mantienen el compilador
oficial) acaban de publicar hdb: un debugger Haskell que
habla Debug Adapter
Protocol. Eso significa que automaticamente funciona en VSCode,
Emacs, Vim, JetBrains, Helix y cualquier editor que entienda DAP. Sin
parroquialismo, sin protocolo propio, plug-and-play con todo lo que ya
tenemos los developers.
Durante VEINTE ANOS la respuesta canonica a "hay debugger en Haskell?" era una excusa muy bien construida. Hoy esa excusa muere. Eso no se celebra todos los dias en este lenguaje.
La excusa de los veinte anos
Si has tocado Haskell alguna vez, la has oido:
"En Haskell la lazy evaluation hace que step-by-step no tenga sentido. Una expresion solo se evalua cuando la fuerzas. Si pones breakpoint en
let x = expensiveComputation, lo unico que ocurre es que x apunta a un thunk; expensiveComputation se ejecuta luego, en otro contexto, posiblemente nunca. Por eso usamos types, property tests, ytrace. Si necesitas debugger es que tu codigo esta mal pensado."
Era una excusa con base tecnica real, no rabieta de fanboys. Y nos la
hemos comido durante dos decadas. La consecuencia: muchas empresas
descartaban Haskell por "no tener debugger decente", y muchos developers
aprendian a pelearse con Debug.Trace.trace
esparcido por el codigo como confeti.
Lo que habia antes (resumen breve)
| Herramienta | Que hacia | Limitacion |
|---|---|---|
Debug.Trace.trace |
printf eterno | trazas en stderr, sin estado, sin pausa |
GHCi :break |
breakpoints en REPL | solo CLI, semantics rotas con lazy |
ghc-debug |
introspeccion heap GHC | low-level, para leaks no para flujo normal |
| HPC | coverage | no es debug |
-fexternal-interpreter |
base tecnica | nadie habia construido encima |
Lo que ha cambiado (GHC 9.14)
Dos cosas que requirieron varios anos de trabajo en el compilador:
Stop points semanticos para lazy code. El runtime ahora distingue "esta expresion ya se evaluo, tienes valor en mano" de "esto sigue siendo thunk pendiente". Eso permite implementar
step outque tenga sentido en presencia de evaluacion perezosa.API estable de breakpoints que un proceso EXTERNO puede consumir sin estar dentro de GHCi.
Sobre esa base, hdb construye:
- Breakpoints (clic en linea)
- Step in / out / over con semantica correcta
- Inspeccion de variables incluyendo thunks (lo unico de Haskell)
- Break on exception
- REPL interactivo dentro del debugger
Y todo eso sale por DAP, asi que cualquier editor moderno lo enchufa sin code custom.
La inspeccion de thunks: la joya
Esta es la parte que me emociona y que va a cambiar como se ENSENA Haskell.
Cuando escribes en Haskell:
let xs = [1..1000000]
n = length (filter even xs)
in print nEn Java o Python esto consume un giga de RAM creando la lista, otro
giga filtrando, y luego cuenta. En Haskell no se crea la
lista: xs es un thunk
perezoso, filter even xs es otro thunk
encima, length fuerza la evaluacion en
streaming. Tres mil cosas que hubiera hecho un imperativo nunca
ocurren.
Pero como ENSENAS eso a alguien que viene de Java? Le dibujas grafos en pizarra. Le pones diagramas en libros. Le sueltas papers academicos. Llevamos 30 anos haciendolo asi.
Con hdb, ahora:
1. pones breakpoint en `let xs = [1..1000000]` 2. paso paso 3. inspeccionas xs --> dice: < THUNK > sin evaluar 4. step over hasta `length` 5. inspeccionas xs --> dice: cabeza forzada, cola pendiente 6. inspeccionas xs --> sigue avanzando, mas elementos resueltos 7. el debugger te DIBUJA el grafo de evaluacion mientras ocurre
Una sesion de quince minutos te da la intuicion que a mi me tomo dos anos de leer libros. Eso es lo que se acaba de regalar al ecosistema.
Por que esto es cultural, no solo tecnico
Tres consecuencias:
1. Los aprendices tienen una via visual
Antes, lazy evaluation era teoria abstracta. Ahora se VE. Eso baja la barrera de entrada radicalmente. Mas gente va a aprender Haskell. Mas gente va a entender lazy. Mas gente va a usar el lenguaje en sitios donde antes era impensable.
2. Las empresas pierden la excusa
"No usamos Haskell porque no tiene debugger" era una afirmacion ridicula en boca de gente que en otros lenguajes nunca usa el debugger porque tienen tests. Pero era un argumento facil en reuniones de comite. Adios.
3. La identidad de la comunidad
Haskell era "el lenguaje donde no hace falta debugger porque los tipos te lo evitan". Ahora es "el lenguaje con debugger DE PRIMERA cuando los tipos no llegan". Mas humilde, mas pragmatico, mas atractivo.
Como se prueba en cinco minutos
Requisito
GHC 9.14 o superior. Si estas en NixOS:
nix shell nixpkgs#ghc nixpkgs#cabal-install
cabal install haskell-debugger --enable-executable-dynamic(En Windows, omite --enable-executable-dynamic. En Mac, igual que
Linux.)
Verifica que esta en PATH:
which hdb
hdb --versionConfiguracion en Emacs Doom
En ~/.config/doom/packages.el:
(package! dap-mode)En ~/.config/doom/config.el:
(use-package! dap-mode
:after lsp-mode
:config
(require 'dap-haskell)
(setq dap-haskell-debug-program '("hdb")))doom sync y reabre.
Sesion test
Abre un fichero Haskell, M-x dap-debug,
elige Haskell. Pon breakpoint con M-x dap-breakpoint-toggle. Step con F10/F11.
Inspect con M-x dap-ui-inspect-thing-at-point.
Si ves un thunk pelarse en vivo, ya estas un paso mas cerca de entender Haskell de verdad.
Donde mete esto en mi plan personal
En el post
de Haskell que escribi hace una hora propuse a Pascual una hora a la
semana, ocho semanas para volver al lenguaje. Esta noticia cambia el
plan: la sesion 4 (cuando toque entender Maybe/Either) DEBE ser con
hdb encendido. La sesion 6 (cuando toque
foldr) tambien. La sesion 8 (cuando toque pelearse con un servidor
Scotty) absolutamente.
Sin debugger durante anos te volvias bueno IMAGINANDO la evaluacion en tu cabeza. Con debugger te haces bueno IMAGINANDO Y VERIFICANDO. La segunda es mas robusta. Y mas rapida.
Cierre breve
Hoy es un buen dia para Haskell. Y un mejor dia para los que estamos volviendo a el. La excusa de "no tiene debugger" muere oficialmente. Bienvenida al tooling de adultos.
Pascual, asi que el lunes a las siete: GHC 9.14, cabal install haskell-debugger, y un breakpoint
en algo bonito. Sin IA. Te lo cuentas tu mismo.
Y a Well-Typed: gracias. Habiamos esperado esto demasiado tiempo.
Comentarios (0)
Sin comentarios todavia. Se el primero!
Deja un comentario