2 puntos por GN⁺ 2024-04-22 | 1 comentarios | Compartir por WhatsApp
  • Racket es un lenguaje maduro centrado en la programación orientada al lenguaje, donde el desarrollo de aplicaciones generales y la creación de nuevos lenguajes se manejan dentro del mismo ecosistema
  • Su núcleo son los macros y #lang, que permiten crear como si fueran bibliotecas nuevas sintaxis, lenguajes específicos de dominio y gramáticas superficiales existentes, y usarlos por módulo
  • La biblioteca estándar, que incluye desde servidor web, bases de datos, matemáticas y estadística, GUI y simulación científica, junto con miles de paquetes, amplía su alcance para desarrollo de propósito general
  • Typed Racket, contratos, sistema de objetos y el IDE DrRacket se ofrecen en conjunto, por lo que se pueden combinar código funcional, componentes orientados a objetos y tipado gradual según la necesidad
  • Racket no es solo un lenguaje de la familia Lisp, sino algo más cercano a un entorno de desarrollo que busca crear lenguajes ajustados a cada dominio del problema y conectar también su ejecución, edición y soporte de herramientas

Racket para programación orientada al lenguaje

  • Racket se presenta a la vez como “Racket, the Programming Language” y “Racket, the Language-Oriented Programming Language”
  • Racket version 9.2 está disponible
  • Es un producto maduro que desde sus inicios ha dado soporte a la programación gráfica multiplataforma en Windows, macOS y Linux
  • Sus funciones básicas de desarrollo incluyen administración de paquetes, GUI, binarios ejecutables independientes e interfaz con sistemas externos

Alcance del desarrollo de aplicaciones generales

  • Racket cuenta con un conjunto de bibliotecas que va desde aplicaciones de servidor web hasta matemáticas y software de simulación científica
  • La documentación representativa y el alcance de las bibliotecas incluyen lo siguiente
  • La caja de herramientas GUI multiplataforma y el servidor web forman parte del ecosistema base
  • Miles de paquetes adicionales se pueden instalar con un solo comando
    • Como ejemplo, hay 3D graphics, Bluetooth socket connector, color maps, data structures, educational software, games, quantum-random number generator, scientific simulations, web script testing, entre otros
  • El ejemplo de #lang racket/gui implementa un pequeño juego de adivinar números en un dialecto GUI y usa varias funciones del lenguaje al mismo tiempo

Un lenguaje que se expande con macros

  • Los programadores de Racket pueden definir sus propios bucles y nueva sintaxis mediante macros
  • La nueva sintaxis se agrega como procedimientos, métodos o clases; basta con crear reglas que reescriban la sintaxis personalizada como expresiones o definiciones de Racket
  • Los macros pequeños ayudan a eliminar código repetitivo que es difícil de resolver con otras funciones
    • Se puede definir una sintaxis time-it para medir el tiempo de ejecución de una tarea
    • Se puede evitar el uso repetitivo de lambda
    • Los macros se exportan desde módulos igual que las funciones normales
  • El sistema completo de macros también permite construir estructuras donde cooperan varios macros
  • Aunque Racket es un lenguaje funcional, desde el principio ha ofrecido el sublenguaje de classes and objects, mixins and traits
  • Su sistema de clases, similar al de Java, está implementado como una biblioteca basada en macros, por lo que funciona sin soporte separado en el lenguaje núcleo

#lang y lenguajes específicos de dominio

  • Racket apunta a ser un lenguaje para crear lenguajes, de modo que los programadores puedan escribir cada módulo en el lenguaje más adecuado
  • El ejemplo de #lang typed/racket usa union type de String y Number, occurrence typing y filtrado de listas
  • El ejemplo de #lang scribble/base trata de un lenguaje de documentación que genera documentos PDF o HTML
  • El ejemplo de #lang datalog usa sintaxis Datalog para definir y consultar relaciones parent y ancestor
  • Se puede crear un nuevo lenguaje en una ventana del IDE y ejecutar módulos de ese lenguaje en otra ventana del IDE, sin necesidad de configuración, archivos de proyecto ni herramientas externas
  • Los usuarios de Racket suelen usar sintaxis con paréntesis, pero también pueden crear gramáticas superficiales existentes que requieran comas y llaves, como Datalog
  • Con los parsing packages, es posible mapear una gramática arbitraria a un lenguaje basado en paréntesis y compilarla a Racket general mediante el sistema de macros de Racket

DrRacket y el ecosistema de desarrollo

  • Racket ofrece su propio IDE, DrRacket, con una función que dibuja una flecha hacia el lugar de definición cuando se pasa el mouse sobre un identificador
  • Incluso al usar lenguajes alternativos como Typed Racket, se puede aprovechar el soporte de edición de DrRacket
  • Los macros de Racket registran y propagan suficiente información de origen incluso en macros complejos o en macros que crean nuevos lenguajes, de modo que DrRacket puede comportarse como si entendiera las nuevas funciones del lenguaje
  • El soporte principal de desarrollo incluye lo siguiente
  • Los recursos del ecosistema incluyen descargas, código fuente, reportes de errores, nightly snapshot builds y repositorio de paquetes
  • Los materiales de aprendizaje y documentación ofrecen Quick Introduction, The Racket Guide, The Racket Reference y All Documentation
  • Entre los canales de la comunidad están Discourse, Discord, Slack, Reddit, mailing lists, Mastodon, Twitter, Blog, Wiki y YouTube; también se ofrecen documentos de Team y Contributing

1 comentarios

 
GN⁺ 2024-04-22
Comentarios de Hacker News
  • Qué gusto ver a Racket en la portada. Desde 1982 he usado sobre todo Common Lisp para programación de investigación, pero últimamente recurro más a Racket
    Hay partes de Racket que no me gustan, pero es casi todo excepto el compilador, el sistema de gestión de paquetes, el IDE GUI, los bindings de Emacs y el hecho de que es un lenguaje agradable de escribir
    No me interesa mucho el ecosistema del lado de la investigación en lenguajes de programación; supongo que probablemente sea la parte que más valoran los profesores de ciencias de la computación que lideran el proyecto. Aun así, espero que les vaya bien
    Por eso siento que me estoy aprovechando del proyecto Racket. Disfruto solo las pequeñas partes que me gustan e ignoro el resto, y casi no contribuyo. Aunque tal vez mi pequeño libro sobre Racket sea una excepción

    • Estoy de acuerdo con casi todo eso. El sistema de gestión de paquetes, el IDE GUI con depurador por pasos, la capacidad del equipo central de Racket para desarrollar y mantener ellos mismos un IDE multiplataforma, y la facilidad para crear binarios ejecutables hacen de Racket mi Lisp favorito
      Estas funciones son de verdad útiles e importantes. Me gusta Lisp, pero en el trabajo solo uso un lenguaje cuando es la mejor herramienta para esa tarea. Gracias a estas funciones, Racket fue el único Lisp cuyo uso realmente pude justificar
      Por la comunidad, las herramientas y el material de aprendizaje, Racket es personalmente un lenguaje fácil de recomendar a otros. También he usado mucho CL y Clojure, y hay cosas que me gustan de ambos, pero cada uno tiene grandes desventajas, así que no los recomendaría a otros
      A mí tampoco me va mucho la parte de investigación del lenguaje ni la funcionalidad lang, y HtDP tampoco me gusta demasiado. Pero creo que esos son solo proyectos que no me interesan hechos en un lenguaje que sí me gusta, no defectos del lenguaje en sí. Porque casi nunca me topo con ellos en la práctica
    • https://leanpub.com/racket-ai/read
      Yo diría que eso ya cuenta como una gran contribución :)
    • Uso CL a diario, y no es para investigación ni para el área de investigación en lenguajes de programación. Aún no he usado Racket, pero me gustaría saber si podrías explicar más qué cosas no te gustan de Racket en comparación con CL
    • Me da curiosidad qué significa exactamente el ecosistema de investigación en lenguajes de programación. En la distribución de Racket, lo único que parece claramente de investigación en lenguajes de programación es Redex
      El lenguaje en sí tiene funciones de metaprogramación, pero todos los lenguajes modernos tienen metaprogramación
      Mi experiencia en la comunidad ha sido, en general, con gente hablando de problemas reales
      Como Racket se usa en investigación de lenguajes de programación y en otras investigaciones, sí se menciona en artículos y presentaciones académicas relacionadas, pero no domina la conversación
      Ejemplo: https://racket.discourse.group/t/levin-tree-search-with-cont...
    • Usé Racket en una clase universitaria sobre ecosistemas de lenguajes de programación, y esa faceta tampoco me resultó muy disfrutable. Aun así, es fácil empezar con Racket y claramente cumple bien su papel. Si alguien quiere meterse a Lisp, personalmente creo que Racket es un buen punto de partida
      Eso sí, Clojure tiene una comunidad más grande y sólida. A cambio, al usar la JVM, la configuración es un poco más engorrosa y también hay más detalles sutiles de los que preocuparse
  • Racket es un lenguaje muy práctico. Si te parece una rareza académica, vale la pena ver qué hace Bogdan Popa con Racket: https://defn.io/
    Personalmente uso Racket cuando necesito un binario con GUI nativa. También sirve bastante bien para parsear cosas como JSON, XML y formatos de archivos de texto
    El libro complementario How to Design Programs, https://htdp.org/2023-8-14/Book/index.html, también es bueno. No enseña exactamente Racket, sino algunos lenguajes educativos implementados sobre Racket, pero tiene ideas que de vez en cuando vale la pena retomar
    El sistema de macros puede parecer raro para alguien que venga de CL o algo parecido, pero una vez que me acostumbré, me resultó relativamente fácil mantener la cordura al hacer metaprogramación
    Aquí van algunos recursos más útiles:
    https://www.greghendershott.com/fear-of-macros/
    https://beautifulracket.com/

    • ¿Hay algo en particular del trabajo de Bogdan que te haya llamado la atención? Lo revisé por encima y nada me saltó especialmente a la vista
  • Me gusta mucho el lenguaje Racket, pero el flujo de trabajo que te imponen es difícil de aceptar. Cuando programo en Python, escribo el código en el editor y lo ejecuto desde el shell
    En Racket eso no funciona tan bien porque el tiempo de arranque es demasiado largo. En cambio, dicen que hay que interactuar con una máquina virtual de larga duración y un REPL
    Pero entonces el código en el que estás trabajando no arranca desde un estado limpio, sino desde el estado que tenga la máquina virtual en ese momento. Es un flujo excelente para algo como Jupyter Notebook, pero no me parece que encaje bien con programas grandes

    • Escribir código en un editor y ejecutarlo desde el shell también es totalmente válido en Racket. En mi experiencia, el tiempo de arranque es bastante parecido al de Python. Sí, es lento, pero no es crítico, y si precompilas, especialmente, está bastante bien. Es útil para archivos en los que ya terminaste de trabajar por el momento
      Usar #lang racket/base en vez de racket también hace una gran diferencia. Hay más detalles en https://docs.racket-lang.org/style/Language_and_Performance....
      Eso de no arrancar desde un “estado limpio” me suena más a un REPL al estilo Common Lisp que a Racket. En Racket normalmente tienes que reiniciarlo al volver a cargar un archivo o módulo, así que terminas con un entorno fresco. La gente se queja de eso, pero yo prefiero el enfoque de estado limpio de Racket al de CL
    • La parte de no arrancar desde un “estado limpio” parece indicar en la documentación que el usuario puede rechazar explícitamente que se guarden archivos de respaldo
      https://docs.racket-lang.org/drracket/drracket-files.html#(p...
      Probablemente también se pueda rechazar la propuesta de restauración
      “Cuando DrRacket se inicia por primera vez, comprueba si quedan archivos de respaldo y, si los hay, propone restaurarlos”
    • Solo tienes que probar Smalltalk :-))
    • Guile podría ser interesante. Sobre todo al depurar, me parece más inmersivo que Racket y también más parecido a Common Lisp (SBCL)
    • Bienvenido al mundo de Smalltalk y las Lisp Machines. Ni siquiera los IDE modernos soportan todavía de verdad hot reload, guardado del estado de trabajo y control de toda la pila de desarrollo en un solo lenguaje
  • Cuando estudiaba en la University of British Columbia, enseñaban Racket en el curso introductorio de ciencias de la computación. Me pareció un gran lenguaje, y como incluso los estudiantes con experiencia previa en programación casi nunca habían visto Lisp, eso ponía a todos en la misma línea de salida
    También me impresionaron las bibliotecas que te permitían hacer juegos simples o visualizaciones con facilidad

    • Yo también tomé esa clase en UBC, pero me dejó una impresión completamente distinta. Fue horrible y, sobre todo, creo que preparó muy mal a los estudiantes de primer ingreso para las clases posteriores de estructuras de datos y algoritmos, que se daban con lenguajes imperativos
      Cuando fui ayudante, muchos de los estudiantes que llegaron a segundo año todavía no sabían ni hacer un for loop, y venían muy rezagados en algoritmos básicos
      No fue hasta el curso de teoría de la computación en cuarto año que desarrollé una appreciation más profunda por los lenguajes funcionales
  • No entiendo cómo se supone que se integren todos estos “lenguajes” de Racket en una sola aplicación. Veo lenguajes como typed/racket, racket/gui, scribble/base, pero no me queda claro cómo hacer, por ejemplo, una aplicación con GUI en código tipado y además generar PDF
    He seguido el tutorial de Racket varias veces, pero sigo confundido sobre cómo unir esos “lenguajes” que parecen no tener relación entre sí
    Personalmente, siento que cada capítulo del tutorial solo explica un “lenguaje” no relacionado, y nunca muestra cómo funcionan juntos. Un capítulo trata del servidor web pero no del sistema de clases, y otro trata de otro “lenguaje” que sí soporta clases, pero ahí no se escribe el servidor web

    • La línea #lang se puede pensar como una especie de directiva del compilador que aplica al alcance de ese archivo. En realidad es mucho más que eso, pero como punto de partida sirve. Si quieres añadir tipos a una aplicación, una buena estrategia es hacerlo archivo por archivo
      Además de la línea #lang, también puedes importar bibliotecas con require, así que puedes poner código de GUI y código del servidor web juntos en un mismo archivo. #lang tampoco está limitado estrictamente a un solo lenguaje a la vez; puedes agregar más cosas en esa línea si no entran en conflicto
    • Me parece una pregunta válida. Si desarrollas una aplicación grande, lo más probable es que casi todo el código esté escrito en el lenguaje "racket". Si te interesan mucho los tipos, una parte considerable podría ser "typed/racket"
      Es cierto que todos los lenguajes comparten una base común y son interoperables hasta cierto punto, pero para nada es probable que termines dividiendo tu programa en cinco partes iguales y usando un lenguaje distinto en cada una. La documentación probablemente sí la escribirías con scribble
      Usar lenguajes distintos puede darte modelos de programación fundamentalmente diferentes, y eso también es parte de lo que hizo posible algo como Typed Racket, pero no debería ser un obstáculo para empezar
      En resumen, solo usa Racket. Si de verdad sientes que necesitas alguna función o estilo de programación diferente, entonces ya buscas si existe un lenguaje que te lo dé. Pero claro, es solo mi opinión
    • Según entiendo, cada módulo te deja elegir el lenguaje de ese módulo
  • Este sitio web, Hacker News, está escrito en Arc y corre sobre Racket: https://en.wikipedia.org/wiki/Arc_(programming_language)

  • El mayor problema de Racket no es el lenguaje ni el ecosistema: https://news.ycombinator.com/item?id=27531508

    • Fui estudiante de la escuela de Racket de 2018 mencionada en el enlace. Todos los instructores, incluidos Felleisen y Butterick, fueron realmente serviciales y amables dentro y fuera del aula.
      Incluso si uno tomara ese enlace completamente al pie de la letra y asumiera que Felleisen se comporta de forma mezquina al estilo Torvalds en ciertas interacciones personales, su trabajo, incluido How To Design Programs, tuvo un impacto muy positivo en mi vida y en la de otras personas. Así que no diría que la gente no debería aprovecharlo
    • Ese es un conflicto muy personal entre miembros conocidos de la comunidad. La comunidad de Racket en general, incluido el equipo central, es muy amable
    • Felleisen es una persona difícil de soportar, pero también es fácil evitarlo. Me parece más un síntoma de las patologías de la academia que de Racket en sí.
      En la comunidad también hay “nerds raros” con opiniones fuertes, así que pueden resultar más molestos precisamente porque su presencia se siente más. Pero, como suele pasar en muchos espacios sociales donde el dinero no impone orden, simplemente así son las cosas
  • Racket es mi lenguaje favorito. Es rápido y práctico, tiene bases sólidas y su modelo de concurrencia también es muy bueno. Se basa en conceptos tomados de Concurrent ML y luego extendidos.
    El sistema de documentación también es excelente y está integrado con el ecosistema de paquetes, así que la mayoría de los paquetes tienen documentación de alta calidad con referencias cruzadas. La compatibilidad hacia atrás también es excelente; me parece mucho mejor que la de Python, que es lo que uso actualmente en mi trabajo principal.
    Por eso, siento que quienes dicen que Racket es demasiado académico o poco práctico probablemente no han profundizado lo suficiente, o fueron estudiantes que en el pasado solo conocieron lenguajes educativos.
    Claro, no es perfecto. La comunidad es pequeña, el uso base de memoria del runtime es alto y, para procesamiento paralelo, hay que levantar una VM de Racket por cada hilo del sistema, entre otros problemas. Aun así, estas son cosas que mejorarán con el tiempo.
    Algunas de las cosas que he hecho con Racket en los últimos años: un sitio de comercio electrónico[1], una app nativa de notificaciones para macOS/iOS publicada en la App Store[2, 3, 4], un cliente de escritorio multiplataforma para Apache Kafka[5, 6, 7], un #lang para Lua[8]. Además de eso, hay varias cosas más[9][10][11]. Me parecen cosas bastante prácticas.
    [1]: https://defn.io/2019/08/20/racket-ecommerce/
    [2]: https://defn.io/2020/01/02/ann-remember/
    [3]: https://defn.io/2024/04/09/ann-remember-for-ios/
    [4]: https://github.com/bogdanp/remember
    [5]: https://defn.io/2022/11/20/ann-franz/
    [6]: https://defn.io/2023/10/15/ann-franz-for-windows/
    [7]: https://defn.io/2023/08/10/ann-franz-source-available/
    [8]: https://defn.io/2022/11/12/ann-racket-lua/
    [9]: https://docs.racket-lang.org/http-easy/index.html
    [10]: https://docs.racket-lang.org/deta/index.html
    [11]: https://docs.racket-lang.org/gui-easy/index.html

    • Bogdan también es el autor de gui-easy y http-easy, que son indispensables en el ecosistema de Racket.
      Además, participa muchísimo en el foro de la comunidad y da un montón de respuestas útiles.
      Me parecía importante mencionarlo porque creo que es un héroe silencioso de este lenguaje. Se puede decir que sus bibliotecas están impulsando código que les hace la vida mucho más fácil a usuarios que no saben nada :)
      https://docs.racket-lang.org/http-easy/index.html
      https://docs.racket-lang.org/gui-easy/index.html
      https://racket.discourse.group
    • La compatibilidad hacia atrás me parece un punto realmente importante. Usé Python intensivamente durante varios años, pero me decepcionó profundamente ver lo poco que les importaba la compatibilidad hacia atrás a los desarrolladores principales y a la comunidad durante la transición 2/3, y después eso no mejoró.
      Quizá se deba a las áreas en las que hoy se usa principalmente Python. La transición de Numeric a Numpy alrededor del año 2000 fue completamente distinta.
      Que algo se rompa cada pocos años puede estar bien para startups unicornio o empresas que se mueven rápido y, literalmente, rompen cosas. Pero también hay muchos programas valiosos para personas y organizaciones que no pueden darse el lujo de reescribir algoritmos maduros cada pocos años o que simplemente no consideran eso una prioridad
  • Uso Racket de vez en cuando y me gusta. Pero me di cuenta de que algunos Lisp, en especial Common Lisp y quizá también Guile, están más infravalorados de lo que pensaba.
    Me gustaría preguntarles a quienes saben más. ¿Qué características de Racket, que al principio no parecen prácticas, relevantes o útiles, resultan inesperadamente útiles para programar una vez que las usas?

  • Hace unos 20 años, antes de que MzScheme se convirtiera en PLT Scheme, trabajé en un software comercial de seguridad de correo electrónico que lo usaba como lenguaje base. El código era multiplataforma y corría en Solaris, Linux y HP-UX, y el código específico por sistema operativo era de unas 1,000 líneas en C.
    Las reglas de filtrado se compilaban al propio Scheme. Incluyendo la UI web, el código total era de unas 30,000 líneas y solo había 5 o 6 desarrolladores.
    Más tarde, después de emigrar, entré a una empresa con un producto parecido pero con menos funcionalidades; ese producto tenía cientos de miles de líneas en C++ y también más desarrolladores.