Janet para mortales (2023)
(ianthehenry.com)- Janet for Mortals es un libro gratuito en línea sobre el lenguaje de programación Janet, pero la retrospectiva se centra más en el proceso de crear un libro técnico con REPL web y proyectos de ejemplo que en el libro en sí
- Todo el trabajo tomó 20 semanas y superó la estimación inicial de 12 semanas para la redacción pura, porque se sumaron tareas adicionales como el sitio web, enlaces con C++, demos en el navegador, un parser de CLI y herramientas de prueba
- El sitio del libro ofrece un REPL integrado con CodeMirror y la gramática de Lezer; el autocompletado consulta el entorno de Janet mediante WebAssembly y
(report)guarda la retroalimentación en SQLite cmd,judge,to doy Toodle.Studio se usan como casos base para mostrar que Janet puede servir para scripting, herramientas CLI, pruebas, ejecución en navegador e interoperabilidad con JavaScript- Justo después del lanzamiento, solo con envíos a Hacker News y Lobsters hubo 30,025 visitantes únicos el viernes, 9,568 el sábado y 3,777 el domingo, pero se estima que solo 387 IP únicas leyeron 5 capítulos o más
Alcance del libro y carga real de trabajo
- Janet for Mortals es un libro gratuito en línea sobre el lenguaje de programación Janet
- El tiempo total de producción fue de 20 semanas en tiempo libre
- La estimación inicial era de 12 semanas, y si se considera solo el tiempo de redacción del texto en inglés, no estuvo tan lejos
- El calendario real incluyó en gran medida proyectos de programación alrededor del libro
- La extensión final fue de 44,000 palabras en prosa en inglés, sin contar fragmentos de código
- Como referencia, The Great Gatsby tiene 47,000 palabras
- Tiene menos de la mitad de la longitud de una serie anterior de textos sobre Nix
- Durante 5 meses, junto con el libro, también se avanzó en lo siguiente
- sitio web del libro
jimmy: enlace a una biblioteca de estructuras de datos persistentes en C++- Toodle.Studio: patio de juegos interactivo de turtle graphics
cmd: biblioteca para parsear argumentos de línea de comandosjudge: framework de pruebas con snapshots inlineto do: gestor de tareas pendiente desde la línea de comandos
Sitio web y REPL integrado
- El mecanismo central del sitio de Janet for Mortals es el REPL integrado
- El usuario puede abrir el REPL en cualquier momento con la tecla Escape
- El REPL queda fijo en la parte inferior de la página y no tapa demasiado el contenido
- El editor usa CodeMirror
- CodeMirror no soporta Janet de forma nativa
- Se tomó como base el soporte del lenguaje Janet creado antes para Bauble
- En el DSL de Bauble no eran importantes sintaxis de Janet como las cadenas
multi`backtick`quoted, pero en el libro sí hacían falta
- Al reforzar la gramática de Lezer que usa CodeMirror, la misma gramática también se reutilizó para el resaltado de sintaxis de los fragmentos de código del libro
- No se encontró ningún generador de sitios estáticos conocido que soportara resaltado para código Janet
- Al principio el libro era en blanco y negro, pero luego se añadieron colores para que la sintaxis poco familiar de Janet se viera más accesible
- El generador de sitio estático fue escrito a mano usando
redo- El núcleo del generador estaba escrito en JavaScript, así que se le pudo integrar la gramática de Lezer
- Toda la configuración estaba unida con shell en una estructura frágil
- Remark se usó tanto para parsear el texto original del libro como para el REPL del cliente
- Se agregó una extensión simple para poner etiquetas a los bloques de código
- Los docstrings de la biblioteca estándar de Janet están escritos en Markdown, así que en el autocompletado del REPL se renderizan a HTML al vuelo
Autocompletado y retroalimentación unidireccional
- El autocompletado del REPL se trató como algo importante para lectores que usan Janet por primera vez
- Al iniciar el REPL, consulta dinámicamente el entorno de Janet a través de WebAssembly
- Aunque el usuario defina un símbolo nuevo con docstring, este no aparece en los resultados de autocompletado
- Se podría regenerar el autocompletado después de cada ejecución de comando, pero se consideró que no valía tanto la pena
- La función
(report)recibe una cadena, la envía por POST a un servidor web simple y el servidor la guarda en una base de datos SQLite- Se parece a una caja de comentarios, pero con la particularidad de enviarse directamente desde el REPL
- Gracias a esta función se leyó retroalimentación y se corrigieron varios errores
- No se implementó ninguna forma de responder
- El backend de report no es Janet, sino una pequeña aplicación en Haskell
- Su única función es recibir solicitudes POST e insertarlas en una base de datos SQLite
- El servidor web no se hizo con Janet
- Se considera que el factor más importante en un servidor web es la seguridad
- No se veía a Janet ni a sus bibliotecas HTTP lo bastante probadas como para exponerlas directamente a internet
jimmy: experimento de interoperabilidad con C++
jimmyes un enlace de Janet para immer- immer es una biblioteca de estructuras de datos persistentes
- El enlace no está terminado, y probablemente no se termine hasta que surja una necesidad real de usarlo
- Aun así, se considera un ejemplo exitoso de cómo interoperar con código C++ desde Janet
Toodle.Studio y Janet dentro del navegador
- Bauble fue un pequeño patio de juegos artístico creado antes, y la primera experiencia incrustando Janet en el navegador
- En ese momento casi no había material sobre cómo incrustar Janet
- Había que usar WebAssembly, Emscripten y TypeScript a la vez en el navegador, lo que elevaba bastante la dificultad
- El resultado final de Bauble fue un sitio web cuya lógica de aplicación estaba escrita en Janet
- La UI usaba bastante JavaScript, pero la lógica principal quedaba a cargo de Janet
- Uno de los motivos importantes para escribir el libro fue querer volver más accesible la técnica de usar Janet en el navegador
- En el libro se eligió construir Toodle.Studio en lugar de Bauble como ejemplo
- Bauble no tenía estado y se parecía a una función pura que transforma una cadena en otra, así que era simple desde el punto de vista de interoperabilidad
- Toodle.Studio es un fork evidente de Bauble, pero la interoperabilidad entre JavaScript y Janet es más compleja
- Toodle.Studio tenía elementos técnicos más adecuados como ejemplo del libro
- Hay que ejecutar programas Janet de larga duración de forma asíncrona a lo largo del tiempo
- El código JavaScript conserva varias referencias al mismo valor de Janet, así que hay que considerar la gestión de memoria
- Hay que pasar estructuras de datos anidadas complejas entre Janet y C++ en ambos sentidos
- El logo de Toodle.Studio es una tortuga animada hecha con Bauble
- Se añadió después de recibir comentarios de que en una demo de turtle graphics no había ninguna tortuga
- Se hizo que sus ojos siguieran el mouse
cmd: parser de argumentos CLI para Janet
cmdes una biblioteca para parsear argumentos de línea de comandos- En el libro solo aparece por unos tres párrafos, pero era necesaria para mostrar con claridad que Janet es un buen lenguaje de scripting
cmdestá fuertemente influido porCore.Commandde OCaml- Se considera que
Core.Commandes la mejor biblioteca de parseo de argumentos de línea de comandos que se ha usado - Se intentó recrear esa experiencia en Janet
- Se considera que
cmdno es tan bueno comoCore.Command- Con tipos, todo se vuelve mucho más fácil
- Aun así, se considera que cubre el 95% de las funciones importantes y que su sintaxis concisa lo vuelve más cómodo para scripts ad-hoc
- Todavía falta la función para generar autocompletado de Bash
Core.Commandlo genera automáticamente- La API de
cmdfue diseñada para poder agregar esta función más adelante
judge: framework de pruebas con snapshots inline
judgefue una de las primeras cosas hechas en Janet en 2021- Después de conocer mejor Janet, se reescribió desde cero
- La API quedó más cómoda de usar
- La implementación también quedó mucho más simple y fácil de cambiar
- La principal diferencia entre Judge v1 y v2 está en la ubicación de las pruebas y los helpers
- Las pruebas pueden estar no solo en el directorio
test/, sino también dentro de archivos fuente normales - Se añadieron los helpers
test-macroytest-stdout
- Las pruebas pueden estar no solo en el directorio
- Se dice que el enfoque equivalente en OCaml para
test-stdoutes prácticamente la única forma que se usa al escribir pruebas de manera profesional- En OCaml no hay una forma especialmente buena de incrustar datos arbitrarios en el código fuente, así que se aborda convirtiéndolo todo en cadenas
- Después de publicar el libro, se añadió a Judge un modo
--interactive- El libro tiene un capítulo sobre pruebas y depuración con Judge
to do: herramienta de tareas hecha en Janet en lugar de Bash
to dose eligió como ejemplo del capítulo de scripting- Era una herramienta no trivial que antes se había hecho en Bash, y la implementación en Bash fue dolorosa
- En Bash, las partes especialmente difíciles fueron el parseo de texto y el manejo de fechas
- Parsear texto multilínea con Sed no era nada agradable
- Se considera prácticamente imposible manipular
datede la misma forma en macOS y Linux
- En Janet, usando PEG,
sh,cmdy otras piezas, se pudieron crear más funciones más rápido que en la lista de tareas original en Bash- Por ejemplo, se añadió la selección múltiple con
fzf - En Bash, construir cadenas terminadas en null se considera difícil
- Por ejemplo, se añadió la selección múltiple con
- El libro solo cubre una versión simplificada
- No incluye función para programar tareas futuras
- No existe el concepto de “saltar” una tarea
- Las funciones centrales son agregar elementos a la lista y marcarlos como completados
- Junto con
zsh-autoquoter, se considera una app sorprendentemente útil
Trabajo de código durante la escritura y mantenimiento
- De las 20 semanas de trabajo en el libro, programar ocupó casi la mitad
- 8 semanas fueron de trabajo de código, y en algunos periodos se escribió y programó al mismo tiempo
- Al principio solo se esperaba mejorar Judge y escribir el parser de argumentos
- Implementar el parser de argumentos fue mucho más difícil de lo esperado
- Como Bauble era demasiado simple, no se anticipó que habría que crear otro patio de juegos artístico nuevo
- La escritura real se hizo en Markdown con Sublime Text
- Sublime Text es el editor preferido para escribir prosa larga
- Mientras se escribía, salieron 2 versiones nuevas de Janet
- Hubo que actualizar los capítulos de depuración y módulos nativos para adaptarlos a los cambios del lenguaje
- Se planea mantener el libro alineado con la versión más reciente de Janet
Reacción al lanzamiento y cuánto se leyó
- La promoción del libro consistió en una publicación en Hacker News, una en Lobsters y algunos tuits
- En Hacker News estuvo todo el día en la portada y durante un tiempo ocupó el primer lugar
- Según los logs de acceso de Nginx, los visitantes únicos fueron los siguientes
- Viernes: 30,025
- Sábado: 9,568
- Domingo: 3,777
- Se considera que estas cifras están más cerca del número de personas que hicieron clic en el enlace que del número de personas que realmente leyeron el libro
- El sitio no tiene analítica de seguimiento del comportamiento del lado del cliente
- Solo se hizo una estimación aproximada con los logs de acceso
- El flujo de visitas entre capítulos no parecía mostrar una buena retención
- El capítulo 1 recibió el 22% de las visitas de la página principal
- El capítulo 2 recibió el 20% de las visitas del capítulo 1
- El capítulo 3 recibió el 69% de las visitas del capítulo 2
- El capítulo 4, “Pegular Expressions”, y el capítulo 9, “Xenofunctions”, tuvieron más visitas que el capítulo 3
- Al cierre del fin de semana de lanzamiento, la mejor estimación del número real de lectores era de 387
- Se tomó como referencia la cantidad de IP únicas que cargaron 5 capítulos distintos o más
Origen del nombre y límites revelados por la retroalimentación
- El nombre del lenguaje Janet viene de Janet, el ser inmortal de The Good Place
- Como ese ser ayuda a mortales a moverse por el más allá, también encaja con el título del libro
- El capítulo menos visitado fue “Testing and Debugging”
- Es el antepenúltimo capítulo del libro
- Se considera que los últimos tres capítulos son los más interesantes del libro
- El enfoque de pruebas de ese capítulo se considera una de las mayores mejoras de productividad de toda una carrera de ingeniería
- A través de la función report del REPL integrado se recibieron 494 mensajes de retroalimentación
- Muchos eran “buen libro” o mensajes de prueba
- Varias decenas fueron reportes de errores tipográficos, solicitudes de explicación y comentarios útiles
- Algunos usuarios enviaron preguntas sin dejar contacto, y como no había función de respuesta no fue posible contestar
- La función report se implementó como una retroalimentación unidireccional muy primitiva
1 comentarios
Opiniones de Hacker News
Tampoco se puede dejar fuera https://bauble.studio/, del mismo autor.
No corre en el navegador de mi computadora vieja, pero cuando estoy estudiando en la biblioteca y quiero tomarme un descanso, suelo jugar unos 30 minutos con bauble en una computadora de la biblioteca.
Es impresionante la cantidad de gráficos que se pueden crear solo cambiando números de un lado a otro, y espero que Janet dure mucho tiempo.
unknown symbol twist.error: script:16:1: compile error: unknown symbol twistin evaluate [lib/evaluator.janet] on line 81, column 7in bauble-evaluator/evaluate [lib/init.janet] on line 8, column 12Es interesante comparar Janet con GNU Guile.
La ventaja original de Guile era que es un lenguaje diseñado para usarse fácilmente junto con C, pero al ser un lenguaje antiguo, parece que todavía no adoptó sensibilidades modernas como incluir de base un gestor de paquetes en la toolchain del lenguaje.
Algo que me gusta de Guile es que puso mucho esfuerzo en explicar su compatibilidad con el estándar RNRS.
No sé qué tan Scheme sea Janet en la práctica, pero me da curiosidad.
Es más como si alguien hubiera creado Clojure sobre Lua.
El libro es https://janet.guide/ y el lenguaje es https://janet-lang.org/.
Me gustó el enfoque práctico de este libro, y es una de las principales razones por las que ahora estoy aprendiendo resolviendo Everybody Codes en Janet.
https://everybody.codes
Me parece desafortunada la expresión “la tortuga es una metáfora”.
La tortuga no era una metáfora, era real: http://classicacorn.computinghistory.org.uk/8bit_focus/logo/...
Claro, encaja con la definición de metáfora como “algo que representa otra cosa, un símbolo”, pero suena como el chiste de confundir el ícono de guardar en disquete con un refrigerador.
Se siente como si faltara el contexto de que antes existía una tortuga de hardware real, divertida y adorable.
Por el título, pensé que era otro asistente de IA inspirado en Janet de The Good Place, pero resultó ser un lenguaje de programación, así que me sorprendió gratamente.
El lenguaje Janet toma su nombre de Janet, el ser inmortal de The Good Place que ayuda a los humanos a navegar el más allá, así que el título también es un chiste ingenioso acorde a eso.
También me sorprendió que venga con PEG (gramática de análisis sintáctico por expresiones) en lugar de un motor básico de expresiones regulares.
Siempre quise que los lenguajes que ofrecen una biblioteca básica de regex incluyeran también una PEG en condiciones.
Ver <https://www.gnu.org/software/guile/manual/html_node/PEG-Pars...>
sporkde Janet ocupa una posición parecida a una especie de libc, y también tiene un submódulo de expresiones regulares, así que es muy probable que esté instalado.Conocí PEG por primera vez con Janet, y me gusta que sea potente y fácil de usar.
Aunque llevo más de 20 años usando regex de a poco, en unos meses llegué a entender mejor PEG.
Dentro de la comunidad de Janet también hay muchas referencias a The Good Place, y varios módulos de terceros llevan nombres de personajes.
elm/regexyelm/parserno vienen incorporados, peroelm/regexrecomienda usar elm/parser en su lugar.Me gusta el origen del nombre, pero si un lenguaje se llama Janet, también parece tener la obligación de priorizar el control.
Leí el libro y me pareció bastante interesante y juguetón, así que hizo que aprender Janet fuera mucho más divertido.
Sin embargo, la documentación del lenguaje era deficiente en varios aspectos.
A menudo las funciones o comandos simplemente estaban listados, sin ejemplos ni explicación, o faltaba la descripción de qué hacían.
Muchas veces no pude encontrar en la documentación funcionalidades que había visto en el libro, y eso terminó siendo una de las razones por las que, aunque me gusta Janet, dejé de aprenderlo.
Me gusta que tenga muchos valores predeterminados sensatos y que se parezca en ciertos aspectos a lenguajes mainstream, en vez de aferrarse a convenciones viejas de Lisp.
Al final, como no son listas cons, en realidad no es Lisp, pero eso está bien.
El problema es que el lenguaje no está suficientemente documentado.
Participo hasta cierto punto en la comunidad de Janet, así que si sé qué partes faltan, puedo contribuir a mejorar la documentación.
A veces solo había una firma de función y ninguna explicación adicional.
Sé que crear documentación amplia toma mucho tiempo y esfuerzo, pero esto pasaba tan seguido que lo dejé y empecé a buscar otro Lisp que compile a binario.
No logré adaptarme bien a Janet, aunque no sé si el problema soy yo.
El único otro Lisp que usé durante bastante tiempo es Emacs Lisp, y Janet es lo suficientemente parecido, pero sutilmente distinto, como para que siguiera cometiendo pequeños errores.
La funcionalidad PEG se veía atractiva en la documentación, pero la sintaxis era incómoda y confusa de manejar.
La documentación era completa en el sentido de que tenía descripciones de todas las funciones, pero era muy escueta y le faltaban ejemplos o información útil de uso.
Tampoco parecía incluir funcionalidades básicas como parsing de JSON.
Si en un lenguaje pensado para escribir scripts rápidos primero tengo que escribir un parser de JSON o XML, la tarea ya fracasó.
Esto fue hace unos 4 años, así que puede que el ecosistema haya mejorado, y también puede que el criterio de evaluar Janet para scripting haya sido incorrecto.
Aun así, este artículo me da ganas de volver a instalarlo.
spork, que ocupa una posición parecida a una especie de libc.Hay una fuerte orientación interna a mantener el núcleo liviano.
Muchos proyectos dependen de
spork, así que es probable que esté instalado desde el principio.La documentación me parece aceptable, pero coincido en que todavía hay vacíos en ejemplos prácticos.
https://janetdocs.com está complementando esa parte y enlaza a “ejemplos de la comunidad” para cada función.
Me salgo del tema, pero gracias a otra entrada del blog original terminé usando un teclado mecánico dividido.
Tenía dolor de hombros y muñecas desde hacía años y me ayudó, así que recomiendo mucho revisar también otros textos de Ian.
Poder presionar
Escen cualquier momento para abrir el REPL integrado pegado en la parte inferior quizá no sea una buena decisión.El navegador ya tiene atajos predeterminados con
Esc, y Firefox sale de pantalla completa al presionarlo.