2 puntos por GN⁺ 2023-08-02 | 1 comentarios | Compartir por WhatsApp
  • La gestión de memoria ORC pasa a ser el valor predeterminado
  • El backend de JavaScript usa BigInt de forma predeterminada para int64 y uint64, por lo que el código que interactúe con el backend JS y use esos tipos podría requerir actualizaciones
  • --experimental:strictEffects queda siempre activado, y los parámetros de callback requieren la anotación effectsOf
  • El lenguaje de marcado predeterminado para los comentarios de documentación cambia del modo RstMarkdown existente a Markdown, y se agregan el pragma {.doctype: Markdown | RST | RstMarkdown.} y los comandos md2html y rst2html
  • Parte de las funciones relacionadas con os de la biblioteca estándar se separan en nuevas interfaces que usan la abstracción Path, disponibles como los módulos std/oserrors, std/envvars, std/paths, std/dirs, std/files, std/symlinks, std/appdirs y std/cmdline
  • Varios módulos de la biblioteca estándar se trasladan a paquetes Nimble, por lo que al usar std/punycode, std/asyncftpclient, std/smtp, std/db_*, std/md5, std/sha1 o std/sums se requiere instalar nimble o atlas
  • Se depreca el uso de un break sin nombre dentro de un block sin nombre, y en versiones futuras se convertirá en error
  • Cambia la definición de "strictFuncs", lo que prohíbe almacenar mediante la desreferenciación de ref o ptr
  • El desempaquetado de tuplas en variables se trata como azúcar sintáctica que se expande a múltiples asignaciones, y ahora es posible el desempaquetado de tuplas anidadas
  • La inferencia top-down se implementa en varios casos predeterminados, por lo que el código de inicialización seq[(float, byte, cstring)] del ejemplo compila
  • Se pueden especificar valores predeterminados para campos de objetos, y esos valores se usan en los campos que no se inicialicen explícitamente
  • Se agrega el switch experimental strictDefs, que verifica que a las variables se les haya asignado explícitamente un valor antes de usarlas, y que las variables let se hayan asignado exactamente una vez
  • En la interoperabilidad con C++ se agregan el pragma virtual y un pragma constructor ampliado, lo que permite definir constructores y proc virtuales que se mapean a constructores y métodos virtuales de C++
  • Se incluye Nimble 0.14, con soporte para lock-file, y la ubicación de almacenamiento de bibliotecas cambia de $nimbleDir/pkgs a $nimbleDir/pkgs2

1 comentarios

 
GN⁺ 2023-08-02
Opiniones de Hacker News
  • Estoy usando Nim en producción con satisfacción. Principalmente creo herramientas de análisis de datos y generación de reportes, y las compilo como ejecutables CLI que invocan scripts del servidor.
    Nim genera ejecutables rápidos y pequeños, y tiene buenas bibliotecas para estructuras de datos JSON heterogéneas y dataframes. Prefiere fuertemente la pila, así que incluso las estructuras de datos dinámicas como secuencias y tablas tienen punteros en la pila que apuntan a datos en el heap, y su vida útil la administra el stack frame.
    Casi no hay referencias dinámicas dentro del programa y no hay que preocuparse por el GC. El sistema de tipos es simple y razonable, y te guía fácilmente hacia código correcto. Los valores predeterminados también están cerca de la transparencia referencial y, salvo que te salgas explícitamente de eso, todo es inmutable y se pasa por valor.
    Los genéricos son potentes y se comportan como se espera, y la sintaxis universal de llamada a funciones es absurdamente útil. Con solo crear procedimientos y funciones que reciban un tipo específico como primer argumento, puedes escribir el equivalente a métodos o interfaces, con lo que esas abstracciones dejan de ser necesarias y la estructura del código se vuelve simple y plana.
    Es tan agradable que me recuerda a cuando descubrí D, pero incluso mejor. Si imaginas un Python compilado nativamente, con anotaciones de tipos, donde casi el 100% es lógica de negocio y no hay relleno, estás cerca de la experiencia de Nim.

    • ¿Esa descripción no es como un vector o map de C++ ubicado en la pila? Asigna internamente cuando hace falta, y todo el contenedor se destruye cuando sale de scope.
    • Me dieron ganas de echarle un vistazo a Nim. Me pregunto cómo será el sistema de build. CMake es realmente doloroso.
    • De verdad se ve como Python. Ojalá se vuelva más popular; parece un Rust mucho más fácil de usar.
    • Se ve bien. Me pregunto en qué estado está la gestión de paquetes y qué tan sólido es el ecosistema actual.
  • Me entusiasma probar esta versión. Como alguien que lleva 25 años programando profesionalmente, veo a Nim como un lenguaje que combina bien lo mejor de varios mundos.
    Es fácil de usar como Python, fuertemente tipado pero con excelente inferencia de tipos, y sus valores predeterminados están pensados para ser rápidos y seguros. Encaja bien desde sistemas embebidos hasta cómputo de alto rendimiento.
    Gracias a UFCS, genéricos y concepts, obtienes las ventajas de la OOP, pero con menos necesidad de escribir código andamiaje para crear interminables relaciones de datos frágiles solo para organizar. A diferencia de Python, la ambigüedad se convierte en un error de compilación.
    Siento que el mismo programa resulta mucho más pequeño, legible y fácil de entender que en la mayoría de los otros lenguajes. Tampoco hay mucha magia ocurriendo detrás, porque los valores predeterminados tienen sentido.
    La metaprogramación en tiempo de compilación está a otro nivel. No es un dialecto aparte ni un juego de sustituciones: está en el núcleo del diseño del lenguaje y es intuitiva de usar. Por ejemplo, es fácil generar código de parsing personalizado a partir de un archivo para eliminar boilerplate repetitivo, y además compila rápido.
    Gracias a su excelente sistema de tipos, es más fácil escribir buen código que en Python, pero con rendimiento comparable a C/C++, y también es muy fácil distribuirlo como ejecutables pequeños e independientes.
    Tiene ABI nativa para C, C++, ObjC y JS, excelente FFI y buena interoperabilidad con Python. Puedes usar directamente los ecosistemas existentes sin reescribirlos.
    Imagina escribir pseudocódigo estilo Python para ESP32, que sin mucho esfuerzo sea muy eficiente y, cuando quieras, también permita control bare-metal. O escribir una app web con backend y frontend en el mismo lenguaje eficiente, hacer un juego rápido de bullet hell y, aun así, no preocuparte por el GC porque todo se asigna en la pila salvo que indiques lo contrario.
    Desde el punto de vista de negocio, también tiene mucho valor que puedas prototipar rápido como en Python, pero que eso ya sea lo suficientemente rápido y liviano para producción. Puede convertirse en el arma secreta de una empresa.

    • Uso Nim como destino de scripting para juegos y otros usos de los que no puedo hablar en detalle. Es porque puede transpilarse a C y C++.
      Me encanta poder administrar directamente el entorno C que está debajo como runtime y, encima de eso, usar un lenguaje moderno de alto nivel donde cosas como JSON tienen excelente soporte de primera clase. Incluso como alguien a quien le gusta Python, Nim es mejor: un Python superior.
    • Me pregunto cómo funciona concretamente eso de escribir una app web con backend y frontend en el mismo lenguaje eficiente.
      En particular, quisiera saber qué tan cómoda es la interoperabilidad con JS durante el desarrollo, y si va más allá de compilar Nim a JS como una biblioteca independiente. ¿Se pueden llamar directamente APIs del navegador desde Nim, o mediante wrappers bastante simples?
    • En casos donde los microsegundos importan, como código que procesa un ADC de 22 kSPS en ESP32, siendo honesto necesité unas 2 horas de ajuste. En ese momento recién estaba aprendiendo Nim, así que el trabajo fue principalmente evitar asignaciones adicionales.
      Aun así, durante unos 4 años no hubo regresiones importantes de rendimiento ni cambios necesarios.
  • Felicitaciones a todas las personas involucradas y a toda la comunidad de Nim. He usado Nim como mi lenguaje principal durante los últimos 10 años, y me gustan mucho las nuevas funciones de Nim 2.0.
    Varias de ellas son verdaderos cambios de juego para mis proyectos. Por ejemplo, los valores predeterminados de objetos podrían, en teoría, permitir que Norm[1] funcione no solo con instancias de objetos, sino también con tipos de objetos. Sin los nuevos enums sobrecargables, Karkas[2] directamente habría sido imposible. Todavía está en desarrollo.
    [1] https://norm.nim.town
    [2] https://karkas.nim.town

    • De los cambios recientes, los valores predeterminados son los que más me gustan. Además de ser útiles en general y reducir aún más el boilerplate de inicialización, permiten garantizar estados válidos en tiempo de compilación en cosas como enums. Probablemente también aplique a variantes de objetos.
  • Nim es un lenguaje realmente bueno para escribir software. Puedes desplegar rápido, desarrollar con gusto y aun así crear software de muy alto rendimiento.
    Dicho eso, en mi experiencia todavía tiene aristas filosas. Hay que coordinar compiladores y opciones de C/C++, los mensajes de error son muy pobres, y algunas bibliotecas solo funcionan con ciertas configuraciones y sistemas. Aun así, considerando que la comunidad es pequeña, es difícil culparlos demasiado. La integración con VS Code funcionó bien y casi no se crasheó.

  • Si Manning Publications ve esto, me gustaría que saliera un libro para la versión más reciente de Nim, y que consideraran otra composición tipográfica con una fuente más legible.
    Compré el excelente libro de Dominik Picheta, pero la edición en papel era tan difícil de leer por la fuente delgada que, aun con lentes graduados, tuve que usar el PDF. Los componentes de la fuente, como los trazos y astas, son demasiado finos.
    Pensé que quizá era problema mío por la edad, así que lo comparé con mi ejemplar original de la 2.ª edición de K&R, y ese libro todavía se lee perfectamente.

  • Reddit escribió sobre cómo usa Nim: https://www.reddit.com/r/RedditEng/comments/yvbt4h/why_i_enj...
    Cada vez más grandes empresas y startups están adoptando Nim. Me entusiasma mucho Nim 2.0 y agradezco enormemente a todos los que contribuyeron.

    • Es interesante eso de que cada vez más grandes empresas y startups lo estén adoptando. Me pregunto si hay estadísticas o datos al respecto, o si es algo anecdótico.
      Aunque sea anecdótico, ¿se pueden mencionar algunos nombres de empresas?
  • Nim ha sido mi lenguaje favorito desde hace un tiempo, y me entusiasma mucho que por fin haya salido la versión 2.0. Muchas de las funcionalidades de esta versión eran muy esperadas.
    El único punto negativo es que, como se menciona al final, algunos módulos incluidos se movieron a repositorios de terceros. No es un gran problema, pero me gustaba que el soporte para SQLite viniera integrado en la biblioteca. Aunque, si empiezas a dar soporte a algunas bases de datos, seguramente tendrás presión para dar soporte a más. Aun así, me sorprende un poco que también hayan quitado el soporte para MD5 y SHA1.

    • Cuando algo entra en una biblioteca “con pilas incluidas”, es fácil que esa biblioteca se estanque. Python arrastra desde los 90 algunas pilas muertas, pero ahí son necesarias.
      Está bien que el soporte para rutas o logging esté en el estándar, pero hay cosas que pueden evolucionar mejor como terceros.
  • Felicitaciones a todos los involucrados. Siento que Nim es un lenguaje realmente interesante.
    Estoy tratando de encontrar un motivo para usarlo en el trabajo. Mi área está alrededor de mobile, así que me resulta atractiva la posibilidad de compilar a JS y ObjC, pero por ahora no he pasado de probar cosas. Comparado con Rust, es mucho más simple empezar.

    • Algo relacionado: con Denim se puede llamar código Nim desde Node.js/Bun: https://github.com/openpeeps/denim
      Funciona creando addons de Node. Es útil para reutilizar código Nim en apps web o para código donde el rendimiento es importante.
  • Revisé Nim hace unos meses y, en cuanto a funcionalidades, tenía muchas cosas que me gustaría que existieran en Python: interoperabilidad sencilla con C/C++, tipado estático, compilación, poder hacer compilación cruzada y ejecutar en Android/iOS, etc.
    Pero, aunque el lenguaje no es nuevo, el ecosistema es pequeño. No hay muchas bibliotecas de alta calidad como numpy, scipy, pandas u opencv en Python. Es una lástima que ningún actor grande lo adopte, y creo que habría sido bueno que Unreal Engine hubiera probado adoptar Nim en lugar de crear su propio lenguaje nuevo de scripting, Verse.
    Otra cosa que se echa de menos es poder interoperar de inmediato con bibliotecas C/C++ sin crear adaptadores manualmente. Sería ideal que bastara con importar los headers.
    También sería bueno tener una interoperabilidad igual de sencilla con Rust. Podría aumentar la adopción, y además en Rust es más fácil encontrar crates multiplataforma de alta calidad que funcionan sin grandes problemas incluso en dispositivos móviles.
    Me preocupa que, en unos años, Python se ponga al día con un Python más rápido, la eliminación del GIL, nuitka y briefcase para mobile, o que Mojo le quite el lugar a Nim.

    • En defensa de Nim, en realidad prácticamente solo Python tiene un ecosistema de machine learning enorme con cosas como numpy, scipy, pandas, opencv, pytorch, tensorflow y keras. Es realmente difícil hacer trabajo de estilo ML/AI en lenguajes que no sean Python.
      Aun así, Nim tiene la biblioteca nimpy, que permite interoperar con Python de forma casi transparente. Es decir, puedes simplemente importar PyTorch, scipy u opencv y usarlos desde Nim.
  • Me da curiosidad saber si alguien tiene experiencia real usando Nim y Zig. Me gustaría escuchar en qué se parecen y en qué difieren. También quisiera ver benchmarks de servidores web idiomáticos en ambos lenguajes, tomando como referencia Nim v2.

    • Usé ambos en un proyecto de OS como hobby. Usé Nim[1] y Zig[2], y prefiero mucho más Nim. El código es conciso y elegante, y me permite concentrarme en la lógica central en vez de pelearme con el lenguaje.
      Zig también es bueno, y me gusta su soporte para valores opcionales y su enfoque para el manejo de errores. Pero me desanimó su sintaxis ruidosa, como !?[]u8, para expresar una unión de error de un puntero opcional a un multipuntero de uint8.
      En la mayor parte del código que requiere asignación dinámica, tener que preparar y pasar asignadores también interfiere con la lógica central. Incluso tareas pequeñas como concatenar o dar formato a cadenas se vuelven trabajo.
      Zig tampoco tiene despacho dinámico, lo que dificulta escribir código polimórfico, y hay que rodearlo con alguna forma de duck typing. Al final decidí que Zig no era para mí.
      [1] https://github.com/khaledh/axiom
      [2] https://github.com/khaledh/axiom-zig
    • Mantengo bindings generados automáticamente para mi biblioteca en C para Zig, Nim, Odin y Rust. Los bindings de Rust definitivamente necesitan ajustes para volverlos más idiomáticos.
      Si miras los ejemplos, en gran medida es el mismo código escrito en varios lenguajes, así que sirven para ver el panorama general, pero en cuanto a funcionalidades del lenguaje apenas rascan la superficie. Por ejemplo, los ejemplos de Zig no usan funcionalidades de comptime.
      Zig: https://github.com/floooh/sokol-zig/tree/master/src/examples
      Nim: https://github.com/floooh/sokol-nim/tree/master/examples
      Odin: https://github.com/floooh/sokol-odin/tree/main/examples
      Rust: https://github.com/floooh/sokol-rust/tree/main/examples
    • Escribí programas en ambos, aunque hace tiempo que no uso Nim. Creo que disfrutaba más escribir código en Nim.
      Zig es más aburrido, pero por buenas razones. Personalmente no escribiría un OS en Nim, pero creo que Zig será excelente para ese uso cuando madure. Yo empecé a usarlo para software embebido.
      Usaría Nim para herramientas CLI, aplicaciones de servidor y quizá también para aplicaciones GUI y juegos.
      El equipo de Zig parece estar invirtiendo mucho más esfuerzo en toda la infraestructura del compilador, y por experiencia es realmente impresionante. Hay innovaciones excelentes.
    • Usé tanto Nim como Zig en proyectos nuevos. Hay muchas diferencias concretas, pero para caracterizarlos de forma simple, Nim está más cerca de intentar crear una navaja suiza tipo Python como lenguaje compilado.
      Zig es un lenguaje mucho más enfocado, que apunta a un nicho específico como sucesor y reemplazo de C, y cumple muy bien ese objetivo.
      Creo que la preferencia por un lenguaje depende de las necesidades y deseos personales que el lenguaje que usas actualmente no logra cubrir. A mí me atrajo el enfoque de apuntar a ser un sucesor de C y por eso me quedé del lado de Zig, pero entiendo por qué otra persona elegiría Nim.
    • Zig no parece tener una implementación en TechEmpower Benchmarks, pero Nim sí: https://www.techempower.com/benchmarks/#section=data-r21&l=y...