1 puntos por GN⁺ 2023-08-09 | 1 comentarios | Compartir por WhatsApp
  • Raku fue evaluado como posible lenguaje calculadora para cubrir el hueco en tareas matemáticas que dejan Python, J, Frink y Excel, y con solo unos experimentos breves dio la impresión de ser un lenguaje muy poderoso, pero extraño
  • Tiene una amplia expresividad centrada en operadores, como símbolos Unicode, operadores infijos alfanuméricos, producto de listas, zip, reduce, acumulación, el matcher ~~ y las secuencias ...
  • El usuario puede definir no solo operadores infijos, sino también operadores circumfix/postcircumfix, y hasta especificar asociatividad de cadena y de lista, además de la asociatividad izquierda y derecha
  • El despacho múltiple no solo ramifica por firmas de tipos, sino también por predicados en tiempo de ejecución con where, y tanto las firmas de funciones como sus parámetros pueden tratarse como valores de primera clase
  • Parece pesado para mantener codebases grandes, pero resulta atractivo para programación a pequeña escala como scripts de una sola vez, cálculos y herramientas personales; sus principales obstáculos son la documentación, el REPL en Windows, la velocidad de compilación y los errores con sigils

Qué llevó a mirar Raku y primera impresión

  • Raku es el lenguaje antes conocido como Perl 6
  • Después de escribir quejas sobre los lenguajes dinámicos, varios usuarios recomendaron Raku, y se revisó para comprobar si servía como lenguaje calculadora para tareas matemáticas
  • Antes se usaba una mezcla de Python, J, Frink y Excel, pero cada uno tenía grandes desventajas
  • La impresión tras unos días de pruebas fue algo parecido a “un lenguaje diseñado por gremlins realmente inteligentes que recopilaron mucho feedback de otros gremlins”

Un sistema de operadores inusual

  • Raku usa activamente operadores Unicode
    • La pertenencia a conjuntos se comprueba con
    • También existen , y
  • También permite operadores infijos alfanuméricos
    • El operador de repetición de cadenas es x
    • La composición de funciones es o
  • Las combinaciones de listas también se expresan con símbolos breves
    • X crea el producto cartesiano de listas
    • Xf aplica f a cada elemento del producto cartesiano
    • Zf hace lo mismo en formato zip
  • Para un operador infijo f, [f] hace reduce de una lista y [\\f] genera resultados acumulados
    • [+] <1 2 3 4 5> es 15
    • [\\+] <1 2 3 4 5> es (1 3 6 10 15)

El matcher ~~ y las secuencias ...

  • ~~ se usa como matcher que maneja varios tipos de comparación con una sola sintaxis
    • "abc" ~~ "abc" comprueba coincidencia de cadenas
    • "abc" ~~ Str comprueba si es de tipo string
    • "abc" ~~ {.chars == 3} comprueba si su longitud es 3
    • "abc" ~~ /^b/ comprueba si abc empieza con b
  • ... crea secuencias detectando un patrón a partir de los valores anteriores
    • 0,1,2...10 aumenta de 1 en 1 desde 0 hasta 10
    • 0,2,4...10 produce una secuencia de pares
    • 1,2,4...10 sigue un patrón de crecimiento como 1 2 4 8

Operadores definidos por el usuario

  • Raku no se limita a definir solo operadores infijos como algunos lenguajes, sino que también permite crear operadores circumfix y postcircumfix
  • Por ejemplo, con sub circumfix:<[∀ zz>($inner){sum($inner)} se puede definir un operador envolvente que sume el valor interno
  • También se puede definir un operador postcircumfix que parezca un producto punto de vectores
    • sub postcircumfix:<| ⟩>(@left, @inside){[+] (@left Z* @inside)}
    • <1 2 3>|<4 5 6>⟩ es 32
  • La asociatividad de operadores también puede configurarse de varias formas
    • Se pueden definir operadores infijos asociativos a izquierda o derecha, como es habitual
    • Se puede especificar asociatividad de cadena, donde x < y < z se interpreta como x < y && y < z
    • También se admite asociatividad de lista, donde a op b op c se convierte en op(a, b, c)

Despacho múltiple y ramificación por condiciones en tiempo de ejecución

  • Raku soporta despacho múltiple, eligiendo la definición adecuada entre varias funciones con firmas de tipos distintas
  • La función de ejemplo f actúa distinto según la combinación de argumentos
    • Si recibe un escalar y un arreglo, suma el escalar a cada elemento del arreglo
    • También soporta el caso de arreglo y escalar
    • Si recibe dos arreglos, suma elemento por elemento con Z+
  • Lo más peculiar es que también puede despachar por predicados en tiempo de ejecución sobre los valores
    • multi my_abs(Int $x where {$x > 0}) {$x}
    • multi my_abs(Int $x) {-$x}
  • La firma de una función es un valor de primera clase, y los parámetros dentro de la firma también lo son

Una superficie amplia creada por pequeñas funciones

  • Si se define una función MAIN, sus parámetros se convierten automáticamente en flags de CLI
  • Los objetos traen una enorme cantidad de métodos predefinidos
    • List object ofrece métodos para obtener todas las permutaciones, todas las combinaciones de tamaño k y todas las ventanas deslizantes
  • Junctions es una forma extraña de valor para hacer varias comparaciones a la vez
    • 1|2 se expande a any(1, 2), por lo que 1 < 1|2 se cumple
    • 1&2 se expande a all(1, 2), por lo que 1 !< 1&2 se cumple
  • Cualquier operador infijo puede volverse un operador negado anteponiendo !
  • Raku parece ser un lenguaje que tiene al mismo tiempo nombres como $kebab-case y resta infija, y se supone que el sigil es lo que permite distinguir x-y
  • La regex syntax no es retrocompatible con Perl 5
    • Durante 30 años los lenguajes siguieron el “estándar” PCRE, pero Perl 6 lo abandonó

Áreas aún no vistas y el atractivo en pequeña escala

  • Lo revisado es solo una parte de las funciones, centrada en su uso como calculadora
  • Aún no se han aprendido el sistema de objetos, los paquetes ni las grammars
  • También faltan muchas funciones por ver, como samewith, que en el cuerpo de una función parece volver a llamar a la misma función con nuevos argumentos
  • Si hubiera que mantener un codebase legado en Raku, probablemente sería muy duro, pero parece potente para la programación In The Small
    • scripts de una sola vez
    • cálculos
    • herramientas personales
    • el tipo de trabajo que se buscaba desde el principio

Quejas y expectativas

  • La documentación es muy escasa y la dependencia de símbolos dificulta la búsqueda
    • Incluso habiendo aprendido varios lenguajes con mala documentación, Raku puede desmotivar porque es mucho más grande y complejo que esos casos
  • En Windows, escribir Unicode en el REPL provoca un crash
  • El compilador también es bastante lento: incluso archivos pequeños tardan más de 0.5 segundos, lo que vuelve doloroso el trabajo iterativo
  • El sistema de sigils es incómodo
    • Se menciona un caso en el que se perdieron 30 minutos depurando un problema por escribir $x en lugar de @x
  • En general, Raku gusta y se espera que tenga éxito, pero también se espera que con el tiempo mejoren el tiempo de compilación y la documentación

1 comentarios

 
GN⁺ 2023-08-09
Opiniones de Hacker News
  • Si ubicáramos los lenguajes de programación en un espacio bidimensional, los ejes podrían ser cuánto sorprenden y, cuando sorprenden, si eso resulta agradable/terrible.
    Uno espera implícitamente que los lenguajes normales estén en la parte inferior izquierda: “casi no sorprenden, pero cuando lo hacen de vez en cuando, es agradable”. Raku, en cambio, da la sensación de apuntar sin disimulo a la rara vez ocupada parte superior izquierda. Es más una actitud de “¿raro, no? ¿no está genial?”.

    • El problema es que esos ejes son subjetivos. Algo puede ser agradable y terrible a la vez; alguna vez escribí JavaScript tipo document.write = function ..., y fue agradable en el sentido de que hizo lo que necesitaba, pero al mismo tiempo fue bastante terrible.
    • Cuando tuve que hacer un parser para una tarea universitaria, descubrí la funcionalidad de grammars de Raku, y como hacía casi todo por mí se sentía como un truco, pero aun así fue divertido.
    • Como originalmente era Perl 6, no sorprende que los desarrolladores de Perl quisieran un lenguaje que no se pareciera en nada a otros lenguajes.
      Perl también tenía muchas “sorpresas agradables”, y creo que Raku fue diseñado principalmente para eliminar las sorpresas terribles de Perl.
    • Entiendo a qué se refiere la parte de comprobar pertenencia a un conjunto con .
      0,2,4...10 se convierte en (0 2 4 6 8 10), pero que 1,2,4...10 se convierta en (1 2 4 8) hace pensar: “¿está buscando el siguiente número en OEIS?”.
    • Raku parecía irse moviendo, a medida que avanzaban los párrafos, cada vez más hacia la parte superior derecha, es decir, la zona de lo sorprendente y terrible.
  • Raku es interesante como lenguaje, pero algunos de sus modismos no me entran bien en la cabeza.
    Parecido a cómo AppleScript se sentía raro al intentar parecer lenguaje natural, mezcla elementos con aire de lenguaje natural como my, say, sub, gather con símbolos como @, declaraciones de módulos y otras decisiones sintácticas que para alguien de afuera se ven bizantinas. El ejemplo de 99 bottles se puede seguir lógicamente, pero sería difícil descubrirlo de forma intuitiva. Se siente como si tuviera muchos símbolos y estuvieran sobrecargados según el contexto, así que incluso para tareas en las que Raku podría ser ideal, como parsers de lenguaje natural, no me darían ganas de usarlo directamente.
    https://examples.raku.org/categories/module-management/Fletc...

    • Parece que no has usado Perl. Con antecedentes en Perl, gran parte de esa sintaxis, en especial el sigil @ para arrays, se ve bastante familiar.
    • Me pasa exactamente lo mismo cuando veo Bash.
  • Mi función favorita de Raku es que tanto la división entera como los literales decimales devuelven Rat, un tipo de número racional.
    Todo el mundo sabe que los números de punto flotante no son muy buenos, pero casi ningún lenguaje intenta realmente alejarse de ellos; en Raku, un literal solo es de punto flotante si usas notación científica.

    • Lenguajes más antiguos como Common Lisp y Scheme también están esperando que los reconozca la gente a la que no le gusta el punto flotante IEEE 754.
      Tienen una jerarquía numérica que incluye racionales e incluso racionales complejos, y por supuesto soportan números de precisión arbitraria. La capacidad de composición es excelente.
    • En la práctica, esto se acerca más a una mala funcionalidad. Si la representación de Rat se vuelve demasiado grande, se convierte automáticamente a punto flotante.
      1/10 es Rat, pero 1/100000000000000000000 se vuelve Num. También existe FatRat, que no se promociona, pero no es el valor por defecto.
    • La jerarquía numérica de Scheme lleva décadas manejando correctamente representaciones exactas.
      Así que más que decir que “se alejó de usar punto flotante inexacto aunque no lo pidieras explícitamente”, lo correcto es ver que nunca estuvo en ese estado para empezar.
    • Racket también diría otra cosa. Funciona correctamente.
      (/ 1.0 3.0) da 0.3333333333333333, (/ 1 3) da 1/3, y (- (+ 0.1 0.2) 0.3) da 5.551115123125783e-17.
    • No estoy seguro de que esto sea bueno. Sé cuándo debería usar tipos decimales/racionales y cuándo punto flotante, pero en mi código personal de Python llamo mucho más a float() que a Decimal().
      Salvo que estés manejando dinero directamente, casi siempre el punto flotante es la opción que quieres.
  • No sentí que la documentación de Raku fuera “realmente pésima”; al contrario, me impresionó que el sitio oficial de documentación sea un recurso integral con documentación conceptual y de API.
    https://docs.raku.org/
    Como punto de partida para la documentación conceptual, esta página es excelente: https://docs.raku.org/language

    • Llevo varios años usando Raku, y la documentación es excelente y a la vez insuficiente.
      La mayor parte de lo que está escrito está bien redactado y tiene ejemplos de código útiles, pero de vez en cuando encuentro partes que directamente no están documentadas o que solo cubren casos simples. En especial, el sistema de módulos fue el mayor problema; la distinción entre módulos y paquetes es difícil de entender solo leyendo la página Modules. Que el espacio de nombres importado pueda ser distinto del espacio de nombres declarado, pero que para que el compilador lo encuentre la estructura de directorios deba coincidir con el espacio de nombres, es útil y curiosamente tiene sentido, pero tuve que aprenderlo probando.
    • Eso se debe a la cultura de Perl. Las FAQ y las páginas de manual de Perl eran de primer nivel gracias al perfil de los programadores que usaban Perl: ingeniosas, concisas y peculiares.
    • Las páginas de manual de Perl siempre fueron excelentes.
  • Todos los geniales operadores Unicode de Raku tienen una notación alternativa en ASCII.
    Por ejemplo, las alternativas de , , , son (elem), !(elem), (cont), !(cont).
    https://docs.raku.org/language/unicode_ascii#Other_acceptabl...

    • Yo definitivamente usaría la versión ASCII.
  • Parece que se siguen repitiendo las críticas típicas que aparecen antes de conocer bien el lenguaje. Antes era el “ruido de línea” de Perl, y ahora es que Raku usa sin pudor operadores Unicode.
    Pero son opcionales, y los probé directamente para que el código se vea compacto y expresivo en pantalla. Encaja bien con un uso cuidadoso y creativo de Unicode. También es común la reacción de que no gustan los sigilos, pero he usado Raku/Perl 6 porque me gusta la expresividad de Perl, como una motosierra navaja suiza, y Raku se siente como Perl elevado al cuadrado en lo que hace que Perl sea Perl. Está más ordenado, es expresivo y tiene una enorme pila de funcionalidades sobre el buen Perl de antaño. La documentación también es buena, aunque necesita seguir mejorándose; comparada con la documentación de Perl, el estándar es muy alto.

    • Me pregunto cómo se ingresan los operadores no ASCII. No sé si es con una distribución especial de teclado, si el editor convierte automáticamente ciertas secuencias o si se usan escapes Unicode en bruto.
      Hacer esto para ahorrarse unos pocos caracteres se ve complicado y no muy significativo.
  • A veces me preguntaba cómo se vería un lenguaje de programación lleno de azúcar sintáctico, y ahora ya lo sé.
    Da una sensación de “es horrible, pero extrañamente atractivo; no puedo apartar la vista, muéstrame más”.

    • Tal vez te guste noulith, un lenguaje de hobby creado por alguien que ganó varios Advent of Code recientes.
      En la descripción de GitHub dice: “slaps roof of [programming language]* this bad boy can fit so much [syntax sugar] into it.”. También ganó el Advent of Code más reciente usando ese lenguaje: https://github.com/betaveros/noulith
    • Espera a conocer los Grammars de Raku.
    • Me pasa lo mismo cada vez que veo C++ moderno.
  • Vale la pena recordar que Raku empezó originalmente como Perl 6, y que buena parte de su filosofía de diseño viene de la forma de pensar de Perl.
    Viendo cómo el autor reacciona de inmediato al operador x para repetir cadenas, parece que no conoce bien la historia de Perl y Raku, pero eso existe en Perl desde hace décadas.

    • En el texto hay una frase que dice “la sintaxis de expresiones regulares no es compatible hacia atrás con Perl 5. Durante 30 años los lenguajes siguieron el ‘estándar’ PCRE, y Perl 6 simplemente lo tiró todo”, así que al menos parece saberlo hasta cierto punto.
    • En la primera nota al pie se dice que Raku antes era conocido como Perl 6.
    • La exageración de que “Perl6/Raku es completamente distinto de Perl 5” está demasiado inflada.
      No se llamó Perl 6 porque sí, y lo desarrolló prácticamente el mismo equipo de Perl. Para alguien que haya usado bastante Perl 5, la herencia de Perl6/Raku es evidente. Incluso todo el modelo de objetos de Raku se parece más a una versión un poco más potente de Moose.pm, el módulo de Perl 5 en CPAN.
  • Sinceramente, la sintaxis de expresiones regulares de Perl 5/PCRE es horrible.
    La única razón por la que existe es que, en la sintaxis antigua de regex, (? era un error de sintaxis y por eso se podía redefinir para cualquier cosa. Raku es un intento de diseñar desde cero un lenguaje de expresiones regulares sensato, ahora que ya sabemos qué deberían expresar las regex. La alternativa es quedar atrapados otros 30 años más en cosas como (?:this|(?>or that)).

    • Más que horrible, es magia negra indescifrable, y una vez que la entiendes es genial.
      Hace mucho que no toco Perl, pero todavía uso expresiones regulares con frecuencia.
    • Estoy de acuerdo, aunque realmente son muy útiles.
  • En cierto sentido, definitivamente es un gremlin. Me gustan las herramientas extrañas y complejas que aumentan la productividad.
    Dicho eso, no estoy de acuerdo con la comparación de “programas grandes vs. programas pequeños”. Alguien menos sensato podría interpretarlo como que es un mal lenguaje para trabajos grandes, pero en realidad puede ser tan bueno como otros lenguajes, o incluso mejor. El problema es que, como con otros lenguajes gremlin, hace falta criterio para usarlo bien. Por ejemplo, casi nadie que haya usado lo suficiente lenguajes parecidos confunde $x con @x. Los sigilos, al leer código, te indican de inmediato el tipo simple de una variable —en Raku, la interfaz—, así que en realidad lo hacen más cómodo, y puedes usar de forma útil el mismo espacio de nombres de variables con distintos sigilos. Se ven raros, parecen caracteres innecesarios y hay que saber qué significan, pero pueden facilitarte la vida: https://www.perl.com/article/on-sigils/
    El problema aparece con quienes no saben bien lo que hacen. Para esas personas, este lenguaje gremlin puede ser una pesadilla viviente, y necesitan muchos dispositivos de protección como defensas de boliche, flotadores, guantes de kevlar, casco y GPS. Eso no significa que no se pueda construir un rascacielos con un lenguaje gremlin; solo que un no gremlin propenso a cometer accidentes no puede hacerlo, mientras que un gremlin sensato sí.

    • Creo que la mentalidad de “esta herramienta solo la puede usar gente suficientemente buena” es un enorme olor de diseño.
      Las herramientas existen para ayudar al equipo a hacer mejor o más rápido el trabajo que necesita hacer. Si usas una herramienta innecesariamente compleja para filtrar juniors o alimentar tu ego, esa herramienta se parece más a un arma contra el resto de la organización que a una ayuda.