- 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∌
- La pertenencia a conjuntos se comprueba con
- También permite operadores infijos alfanuméricos
- El operador de repetición de cadenas es
x - La composición de funciones es
o
- El operador de repetición de cadenas es
- Las combinaciones de listas también se expresan con símbolos breves
Xcrea el producto cartesiano de listasXfaplicafa cada elemento del producto cartesianoZfhace 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>es15[\\+] <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" ~~ Strcomprueba si es de tipo string"abc" ~~ {.chars == 3}comprueba si su longitud es 3"abc" ~~ /^b/comprueba siabcempieza conb
...crea secuencias detectando un patrón a partir de los valores anteriores0,1,2...10aumenta de 1 en 1 desde0hasta100,2,4...10produce una secuencia de pares1,2,4...10sigue un patrón de crecimiento como1 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>⟩es32
- 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 < zse interpreta comox < y && y < z - También se admite asociatividad de lista, donde
a op b op cse convierte enop(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
factú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|2se expande aany(1, 2), por lo que1 < 1|2se cumple1&2se expande aall(1, 2), por lo que1 !< 1&2se cumple
- Cualquier operador infijo puede volverse un operador negado anteponiendo
! - Raku parece ser un lenguaje que tiene al mismo tiempo nombres como
$kebab-casey resta infija, y se supone que el sigil es lo que permite distinguirx-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
$xen lugar de@x
- Se menciona un caso en el que se perdieron 30 minutos depurando un problema por escribir
- 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
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?”.
document.write = function ..., y fue agradable en el sentido de que hizo lo que necesitaba, pero al mismo tiempo fue bastante terrible.Perl también tenía muchas “sorpresas agradables”, y creo que Raku fue diseñado principalmente para eliminar las sorpresas terribles de Perl.
∈.0,2,4...10se convierte en(0 2 4 6 8 10), pero que1,2,4...10se convierta en(1 2 4 8)hace pensar: “¿está buscando el siguiente número en OEIS?”.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,gathercon 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...
@para arrays, se ve bastante familiar.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.
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.
Ratse vuelve demasiado grande, se convierte automáticamente a punto flotante.1/10esRat, pero1/100000000000000000000se vuelveNum. También existeFatRat, que no se promociona, pero no es el valor por defecto.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.
(/ 1.0 3.0)da0.3333333333333333,(/ 1 3)da1/3, y(- (+ 0.1 0.2) 0.3)da5.551115123125783e-17.float()que aDecimal().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
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.
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...
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.
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”.
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
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
xpara repetir cadenas, parece que no conoce bien la historia de Perl y Raku, pero eso existe en Perl desde hace décadas.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)).Hace mucho que no toco Perl, pero todavía uso expresiones regulares con frecuencia.
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
$xcon@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í.
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.