Raku (lenguaje de programación)

lenguaje de programación
(Redirigido desde «Perl 6»)

Raku es un miembro de la familia de lenguajes de programación Perl.[6]​ Inicialmente conocido como Perl 6, se renombró a Raku en octubre de 2019.[7][8]​ Raku presenta elementos de muchos lenguajes modernos e históricos. No fue una meta ser compatible con Perl, aunque la retrocompatibilidad es parte de la especificación. El proceso de diseño de Raku comenzó en el año 2000.

Raku
Camelia, la mascota de Raku[1]
Desarrollador(es)
La comunidad de Raku
https://raku.org/ y https://perl6.org/
Información general
Extensiones comunes .raku, .rakumod, .rakudoc, .rakutest, .t[2]
Paradigma multiparadigma
Apareció en 25 de diciembre de 2015 (8 años y 4 meses)
Diseñado por Larry Wall
Última versión estable 6.d 'Diwali'[3](24 de octubre de 2020 (3 años, 6 meses y 1 día))
Sistema de tipos dinámico, gradual
Implementaciones Rakudo
Influido por Perl, Ruby, Smalltalk, Haskell,[4]JavaScript
Ha influido a Perl,[5]Haskell,[5]​ AntLang
Sistema operativo Multiplataforma
Licencia GPL o Licencia Artística 2

Historia editar

En Perl 6, decidimos que sería mejor arreglar el lenguaje que arreglar al usuario.
Larry Wall[9]

El proceso de diseño de Raku se anunció por primera vez el 19 de julio de 2000, en el cuarto día de la Conferencia Perl anual,[10]​ por Larry Wall, en su charla State of the Onion 2000.[11]​ En ese momento, los objetivos primarios eran eliminar las "verrugas históricas" del lenguaje; "las cosas sencillas deberían continuar siendo sencillas, las cosas difíciles deberían ser más fáciles, y las cosas imposibles deberían ser difíciles"; una limpieza general del diseño interno y de la API. El proceso comenzó con una serie de peticiones de comentarios o "RFC". Este proceso estuvo abierto a todos los contribuyentes, y no dejó ningún aspecto del lenguaje cerrado al cambio.[12]

Una vez que el proceso de las RFC se completó, Wall revisó y clasificó cada una de las 361 peticiones. Empezó entonces el proceso de escribir los "Apocalipsis", un término que originalmente se refiere a la "revelación".[13]​ Mientras que el objetivo original era escribir un Apocalipsis por cada capítulo de Programming Perl, a medida que se iba escribiendo cada uno, se hizo obvio que los cambios previos iban siendo invalidados por los posteriores. Por esta razón, se publicaron un conjunto de Sinopsis, cada una relacionada con los contenidos de un Apocalipsis, pero reflejando los cambios posteriores. Hoy, la especificación de Raku se gestiona a través del paquete de pruebas[14]​, mientras que las Sinopsis se mantienen como referencia histórica.[15]

Existen también una serie de Exégesis escritas por Damian Conway que explican los contenidos de cada Apocalipsis en términos de uso práctico. Cada Exégesis contiene ejemplos de código junto con la discusión del uso y las implicaciones de los ejemplos.[16]

A día de hoy, se usan tres métodos de comunicación en el desarrollo de Raku. El primero es el canal de IRC #raku. El segundo es un conjunto de listas de correo.[17]​ El tercero es el repositorio de código fuente Git alojado en Github.[18]

Objetivos iniciales y consecuencias editar

El objetivo principal que Larry Wall sugirió en su conferencia inicial fue la eliminación de las "verrugas históricas", que hacían referencia, por ejemplo, a la confusión que rodea el uso del sigilo (sigil) para los contenedores de datos; la ambigüedad entre las funciones select; el impacto sintáctico de los identificadores de archivo de palabra simple. Existían muchos otros problemas que los programadores de Perl habían discutido cómo arreglar durante años y fueron algunos de los primeros temas tratados por Larry en su conferencia.[cita requerida]

Una consecuencia de estos objetivos fue que Perl 6 no retendría retrocompatibilidad con la actual base de código de Perl. Esto significa que el código interpretado correctamente por un compilador de Perl 5 no será aceptado por un compilador de Perl 6. Ya que retener la retrocompatibilidad es un objetivo normal en la mejora del software, la ruptura de compatibilidad entre Perl 5 y Perl 6 se estableció explícitamente. Las diferencias entre Perl 5 y Perl 6 se hicieron tan grandes que, llegado el momento, Perl 6 se renombró a Raku.

Mascota editar

 
Larry Wall y Camelia

El nombre de la mascota es "Camelia, el bicho de Raku".[1]​ Su nombre es una referencia a la mascota del dromedario asociado a Perl, y su forma, siguiendo la tradición amorosa de la comunidad Perl, es una reproducción de un "error de software". Los diseños en espiral incrustados en sus alas recuerdan las letras "P6", la abreviatura de Perl 6.

Implementaciones editar

En 2017, solo está bajo desarrollo activo la implementación Rakudo. Ninguna implementación se designará como la oficial de Raku; en su lugar, "Raku será cualquier cosa que pase el conjunto de test oficial".[19]

Rakudo Perl 6[20][21]​ se compila para diversas máquinas virtuales, como MoarVM, la máquina virtual Java y Javascript. MoarVM es una máquina virtual construida especialmente para Rakudo perl 6[22]​ y la cadena de montaje del compilador NQP.[23]​ Existe una capa entre Raku y las máquinas virtuales, llamada Not Quite Perl 6, o NQP, que implementa las reglas de Raku para la interpretación de Raku, así como el Árbol de sintaxis abstracta y la Generación de código específico de la arquitectura. La mayor parte de Rakudo se ha escrito en el mismo Raku, aunque no se trate de una implementación auto contenida, ni existan planes concretos, en este punto, para que Rakudo sea un compilador completo y autosuficiente.

Implementaciones históricas editar

Pugs fue una implementación inicial de Perl 6 escrita en el lenguaje de programación Haskell. Pugs se utilizaba como la implementación más avanzada de Perl 6, pero desde mediados del 2007 está prácticamente dormido (solo han aparecido desde entonces actualizaciones para las nuevas versiones de GHC). Desde noviembre de 2014, Pugs ya no recibe mantenimiento.[24]

En 2007, v6-MiniPerl6 ("mp6") y su reimplementación, v6-KindaPerl6 ("kp6") se escribieron como un medio para arrancar el Perl-6.0.0 STD, usando Perl. El STD es una gramática completa para Perl 6, y está escrito en Perl 6. En teoría, cualquier cosa capaz de analizar el STD y generar el código ejecutable es un adecuado sistema de arranque para Perl 6. kp6 está actualmente compilado por mp6 y puede trabajar con múltiples entornos finales.[25][26]​ mp6 y kp6 no son implementaciones completas de Perl 6, y están diseñadas solo para implementar el conjunto de características mínimas para arrancar un completo compilador de Perl 6.

Yapsi es un compilador e intérprete de Perl 6 escrito en el propio Perl 6. De resultas de esto, requiere de la existencia de un intérprete de Perl 6, como el de Rakudo Star, para poder ejecutarse.[27]

Niecza, otra principal implementación de Perl 6, se centraba en la investigación de la optimización e investigación de una implementación eficiente. Se dirige al Common Language Infrastructure.[28]

Sistema de módulos editar

La especificación de Raku solicita que los módulos se identifiquen por nombre, versión y autoría.[29]​ Es posible cargar solo una versión específica de un módulo, o incluso dos módulos del mismo nombre que se diferencian en la versión o la autoría. Por comodidad, su puede indicar un nombre corto como un alias del módulo.

CPAN, el sistema de distribución de módulos de Perl, todavía no maneja módulos Raku. En su lugar, se usa un prototipo de un sistema de módulos.[30]

Principales cambios con respecto a Perl editar

Perl y Raku difieren fundamentalmente, aunque en general la intención es la de "mantener Raku como Perl", así que claramente Raku es "un lenguaje de programación Perl". La mayor parte de los cambios están dirigidos a normalizar el lenguaje, para hacerlo más fácil de entender para los programadores tanto novatos como expertos, y hacer "las cosas fáciles más fácilmente y las difíciles, más posibles".

Una especificación editar

Una principal, pero no técnica, diferencia entre Perl y Raku es que Raku comienza como una especificación.[19]​ Esto significa que, si es necesario, Raku puede ser reimplementado, y también significa que los programadores no necesitan leer el código fuente como último recurso para consultar el funcionamiento de alguna característica. En contraste, en Perl, la documentación oficial no se considera autorizada, y solo describe el comportamiento real del intérprete de Perl de forma informal. Las discrepancias encontradas entre la documentación y la aplicación pueden dar lugar a que se cambie uno para reflejar al otro, una dinámica que impulsa el continuo desarrollo y perfeccionamiento de las versiones de Perl.

Sistema de tipos editar

En Raku, el sistema de tipos de Perl se ha aumentado con la adición de tipos estáticos.[31]​ Por ejemplo:

my Int $i = 0;
my Num $n = 3.142;
my Str $s = "Hola mundo";

Sin embargo, el sistema de tipos estático es algo opcional, por lo que los programadores pueden hacer la mayor parte de las tareas sin usar ninguna clase de tipificado:

my $i = "25" + 10; # $i es 35

Raku ofrece un sistema híbrido de sistema de tipos gradual donde el programador puede elegir usar sistema de tipos estático, dinámico, o una mezcla de los dos.

Lista formal de parámetros de subrutinas editar

Perl define las subrutinas sin listas de parámetros formales (aunque un simple conteo de parámetros y un flojo chequeo de tipos se pueden hacer con los "prototipos" de Perl). Los argumentos pasados a las subrutinas se convierten en alias dentro del array @_. Si los elementos de @_ se modifican, los cambios se reflejan en los datos originales.

Raku ofrece unos verdaderos parámetros formales.[32]​ En Raku, una declaración de subrutina se parece a algo como esto:

sub hacer_algo(Str $cosa, Int $otra) {
     ...
}

Como en Perl, los parámetros formales (es decir, las pseudo-variables en la lista de parámetros) son alias de los parámetros actuales (los valores pasados dentro), pero por defecto, los alias se marcan como constantes por lo que no se pueden modificar. Pueden ser declaradas explícitamente como alias de lectura-escritura del valor original o como copias usando respectivamente las directivas is rw o is copy que el programador requiere para indicar que los valores serán modificados localmente.

Modos de pasar parámetros editar

Raku proporciona tres modos básicos de la transmisión de parámetros: parámetros posicionales, parámetros por nombre, y parámetros absorbentes.

Los parámetros posicionales son la típica lista ordenada de parámetros que la mayoría de los lenguajes de programación usan. Todos los parámetros también pueden transmitirse mediante el uso de su nombre en una manera desordenada. Un parámetro por nombre solo se puede pasar especificando su nombre (indicado por un : antes del nombre del parámetro) solo se puede pasar especificando su nombre, es decir, nunca captura un argumento posicional. Los parámetros absorbentes (indicados con un * antes del nombre del parámetro) son la herramienta de Raku para la creación de funciones variadic. Un hash absorbente capturará los restantes parámetros pasados por nombre, mientras que un array absorbente capturará el resto de parámetros que se pasen por posición.

He aquí un ejemplo del uso de los tres modos de paso de parámetros:

sub algunaFuncion($a, $b, :$c, :$d, *@e) (
  ...
)

algunaFuncion(1, 2, :d(3), 4, 5, 6); # $a = 1, $b = 2, $d = 3, @e = (4, 5, 6)

Los parámetros posicionales, como los indicados antes, siempre se requieren a no ser que se sigan con un ? para indicar que son opcionales. Los parámetros con nombre son opcionales por defecto, pero se pueden marcar como requeridos con la adición de ! después del nombre de la variable. Los parámetros absorbentes son siempre opcionales.

Bloques y clausuras editar

Los parámetros también se pueden pasar a bloques arbitrarios, que actúan como clausuras. Así es como, por ejemplo, se indican los iteradores de los bucles for y while. En el ejemplo siguiente, una lista se recorre, tres elementos a la vez, y se pasa al bloque del bucle como las variables, $a, $b y $c.[33]

for @list -> $a, $b, $c {
    ...
}

Esto se conoce generalmente como un "sub puntado" o "bloque puntado", y la flecha se comporta casi exactamente igual que la palabra clave sub, al presentar una clausura anónima (o subrutina anónima en terminología de Perl).[32]

Invarianza del sigilo editar

En Perl, los sigilos –los caracteres especiales que preceden a los nombres de variables– cambian dependiendo de cómo se use la variable:

# Perl
my @array = ('a', 'b', 'c');
my $elemento = $array[1];    # $elemento es 'b'
my $elemento = @array[1];    # en 5.10, $elemento es 'b', con un aviso adicional
my @extracto = @array[1, 2]; # @extracto es ('b', 'c')

En Raku, los sigilos son invariantes, lo que significa que no cambian, tanto si se trata de un array entero o de un solo elemento del array:[31]

# Raku
my @array = 'a', 'b', 'c';
my $elemento = @array[1];    # $elemento es 'b'
my @extracto = @array[1];    # @extracto es ('b')
my @extracto = @array[1, 2]; # @extracto es ('b', 'c')

La varianza en Perl se inspiró por el número del plural, algo muy común en muchos idiomas:

"Esta manzana"            # CORRECTA
"Estas manzanas"          # CORRECTA
"Esta tercera manzana"    # CORRECTA
"Estas tercera manzana"   # INCORRECTA

Sin embargo, este mapa conceptual se rompe cuando las referencias entran en juego, ya que pueden referirse a contenedores a pesar de que sean escalares. Así, manejar estructuras de datos anidadas puede requerir una expresión tanto en forma singular como plural, en un solo término:

# Perl: recuperar una lista desde el nodo de un ''hash'' que contiene unos ''hash'' que contienen ''array''
my @verbos_transitivos = @{ $diccionario{ 'verbo' }{ 'transitivo' } };

Esta complejidad no tiene equivalencia ni en el uso común del lenguaje natural ni en cualquier otro lenguaje de programación, y causa una alta carga cognitiva al escribir código para manipular complejas estructuras de datos. Este es el mismo código en Raku:

# Raku: recuperar una lista desde el nodo de un ''hash'' que contiene unos ''hash'' que contienen ''array''
my @verbos_transitivos = %dictionario{ 'verbo' }{ 'transitivo' }.<>;

Programación orientada a objetos editar

Perl soporta Programación orientada a objetos mediante un mecanismo conocido como bendición. Cualquier referencia se puede bendecir para ser un objeto de una determinada clase. Un objeto bendecido puede tener métodos invocados en ella utilizando la sintaxis "flecha" que hará que Perl localice o "despache" una subrutina apropiada según el nombre, y la llame con la variable bendecida como su primer argumento.

Si bien este modelo es extremadamente poderoso, hace que el caso más común de la orientación a objetos -un objeto como si fuera una estructura de datos con algo de código asociado- innecesariamente complicado. Además, debido a que Perl no puede hacer suposiciones sobre el modelo de objetos en uso, la invocación de métodos no se puede optimizar muy bien.

En el espíritu de hacer "las cosas fáciles, fáciles, y las cosas difíciles, posibles", Raku mantiene el modelo de la bendición, y proporciona un modelo de objetos más sólido para los casos comunes.[34]​ Por ejemplo, una clase para encapsular un punto de coordenadas cartesianas se puede definir y utilizar de esta manera:

class Punto is rw {
    has $.x;
    has $.y;

    method distancia( Punto $p ) {
        sqrt(($!x - $p.x) ** 2 + ($!y - $p.y) ** 2)
    }

    method distancia-al-centro {
        self.distancia: Punto.new(x => 0, y => 0)
    }
}

my $punto = Punto.new( x => 1.2, y => -3.7 );
say "Posición del punto: (", $punto.x, ', ', $punto.y, ')';
# SALIDA: Posición del punto: (1.2, -3.7)
# Ahora cambiamos x e y (note que los métodos "x" e "y" se usan como valor a la izquierda):
$punto.x = 3;
$punto.y = 4;
say "Posición del punto: (", $point.x, ', ', $point.y, ')';
# SALIDA: Posición del punto: (3, 4)

my $otro-punto = Punto.new(x => -5, y => 10);
$punto.distancia($otro-punto); #=> 10
$punto.distancia-al-centro;    #=> 5

El punto reemplaza a la flecha como un gesto a muchos otros lenguajes, (por ejemplo, C++, Java, Python, Ruby, etc.), que acordaron el uso del punto como la sintaxis para la invocación de métodos.

En la terminología de Raku, $.x se llama un "atributo". Algunos lenguajes llaman a esto campos o miembros. El método utilizado para acceder a un atributo se llama un descriptor de acceso. Los métodos automáticos de acceso son métodos que se crean automáticamente, y se nombran con el mismo nombre que el atributo. Estas funciones de acceso devuelven el valor del atributo. Cuando una clase o un atributo individual se declara con el modificador is rw (abreviatura de "lectura/escritura"), al accesor automático se le puede pasar un nuevo valor para establecer el atributo, o puede asignarse directamente como un valor a la izquierda (como en el ejemplo). Los accesores automáticos se pueden sustituir por los métodos definidos por el usuario, si el deseo del programador es tener una interfaz más completa de un atributo. Los atributos solo se pueden acceder directamente desde el interior de una definición de clase por medio de la sintaxis $! sin importar cómo se declararon los atributos. Todos los demás accesos deben hacerse a través de los métodos de acceso.

El sistema de objetos de Raku se ha inspirado por el entorno de trabajo Moose que introduce muchas de las características de la programación orientada a objetos de Raku a Perl 5.

Herencia, roles y clases editar

Herencia es la técnica por la que un objeto o tipo puede reutilizar código o definiciones de objetos o tipos existentes. Por ejemplo, un programador puede querer tener un tipo estándar pero con un atributo extra. La herencia en otros lenguajes, tales como Java, se proporciona permitiendo a las clases ser subclases de clases existentes.

Raku proporciona herencia por medio de clases, que son similares a las clases de otros lenguajes, y de los Roles.

Roles en Raku toman la función de las interfaces en Java, mixins en Ruby, y rasgos[35]​ en la variante Squeak de Smalltalk. Son como las clases, pero ofrecen un mecanismo de composición más seguro.[36]​ Se utilizan para realizar composición con otras clases en lugar de añadirse como en la cadena de herencia. Los roles definen tipos nominales; proporcionan nombres de semántica para las colecciones de comportamiento y estado. La diferencia fundamental entre un rol y una clase es que las clases pueden ser instanciadas; los roles, no.[37]

Aunque los roles son distintos de las clases, es posible escribir código Raku que instancie directamente un rol o use un rol como un objeto tipo; Raku creará automáticamente una clase con el mismo nombre que el rol, haciendo posible usar transparentemente como si fuera una clase.[38]

En esencia, un rol es un conjunto (posiblemente abstracto) de métodos y atributos que se pueden agregar a una clase sin necesidad de utilizar herencia. Un rol también se puede añadir a un objeto individual; en este caso, Raku creará una subclase anónima, agregará el rol a la subclase, y cambiará la clase del objeto a la subclase anónima.

Por ejemplo, considere lo siguiente. Un Perro es un Mamífero porque los perros heredan ciertas características de los mamíferos, como las glándulas mamarias y (a través de los antecesores de los mamíferos, los Vertebrados) una espalda. Por otra parte, los perros pueden tener uno de diversos tipos de comportamientos, y estos comportamientos pueden cambiar en el tiempo. Por ejemplo, un perro puede ser una Mascota, asilvestrarse, o ser un Perro_guía para los ciegos (los perros-guía son entrenados, así que no empiezan su vida como perros-guía). Sin embargo, estos son simplemente conjuntos de comportamientos adicionales que se pueden agregar a un perro. También es posible describir estos comportamientos de tal manera que puedan ser aplicados a otros animales, por ejemplo, un Gato, que también puede ser doméstico o silvestre. Por lo tanto, Perro y Gato son distintos entre sí, mientras que ambos se mantienen dentro de la categoría más general de Mamífero. Así, Mamífero es un clase y Perro y Gato son clases que heredan de Mamífero. Pero los comportamientos asociados con Mascota, Silvestre y Perro_guía son roles que se pueden añadir a las clases o a objetos instanciados desde las clases.

class Mamífero is Vertebrado {
    ...
}
class Perro is Mamífero {
    ...
}
role Mascota {
    ...
}
role Silvestre {
    ...
}
role Perro_guía {
    ...
}

Los roles se agregan a una clase o un objeto con la palabra clave does. Para mostrar la herencia desde una clase, existe la palabra clave is. Las palabras clave reflejan los diferentes significados de las dos características: composición con un rol da a una clase el comportamiento del rol, pero no indica que sea la misma cosa que el rol.

class PerroGuía is Perro does Perro_guía {
    ...
}   # Subclase dotada con un rol

my $perro = new Perro;
$perro does Perro_guía;                         # Objeto individual dotado con un rol

Aunque los roles son distintos de las clases, los dos son tipos, por lo que un rol puede aparecer en una declaración de variable, donde normalmente se pondría una clase. Por ejemplo, un rol Ciego para un Humano puede incluir un atributo del tipo Perro_guía; este atributo podría contener un Perro_guía, un Caballo guía, a Guía Humano, o incluso una Guía Mecánica.

class Humano {
    has Perro $perro;                           # Puede contener cualquier clase de Perro, tanto si hace el
    ...                                         # rol de Guía o no
}
role Ciego {
    has Perro_guía $guía;                       # Puede contener cualquier objeto que tenga un rol de Perro_guía,
    ...                                         # tanto si es un Perro o cualquier otro
}

Expresiones regulares editar

Las expresiones regulares y el procesado de texto de Perl han sido siempre unas de sus características definitorias.[39]​ Debido a que desde hace un tiempo las construcciones de emparejamiento de patrones en Perl han excedido las capacidades de las expresiones regulares de los lenguajes formales,[40]​ la documentación de Raku se referirá a ellas exclusivamente como regexen (contractura inglesa de 'regular' y 'expression'), distanciándose del término empleado en la definición formal.

Raku proporciona un superconjunto de las posibilidades de Perl con respecto a las regexes, incluyéndolas en un gran entorno de trabajo llamado "reglas" (rules, (en inglés)) que ofrecen las posibilidades de los formalismos del análisis sensible al contexto (como el predicado sintáctico del analizado de expresiones gramaticales y Antlr), así como actuar como una clausura con respecto a su ámbito léxico[41]​ Las reglas se presentan con la palabra clave rule que tiene un uso muy similar a la definición de subrutinas. Reglas anónimas se pueden definir con la palabra clave regex (o rx), o pueden, simplemente, usarse incluidas como las expresiones regulares donde en Perl se usarían los operadores m (coincidencia o emparejamiento) o s (sustitución).

En el Apocalipsis 5, Larry Wall enumeró los 20 problemas de la "actual cultura regex". Aparte de que las expresiones regulares de Perl fueran "demasiado compactas y 'lindas'", tenían "demasiada confianza en muy pocos meta-caracteres", "pequeño soporte para capturas con nombre", "pequeño soporte para gramáticas" y "pobre integración con el lenguaje 'real'".[42]

Simplificación sintáctica editar

Algunas construcciones de Perl se han cambiado en Raku, optimizadas para pistas sintácticas diferentes para los casos más comunes. Por ejemplo, los paréntesis requeridos en las estructuras de control en Perl ahora son opcionales:[33]

if es_verdadero() {
   for @array {
      ...
   }
}

También, el operador , (coma) es ahora un constructor de lista, así que los paréntesis ya no son necesarios alrededor de las listas. El código

@array = 1, 2, 3, 4;

hace que @array sea un array con, exactamente, los elementos '1', '2', '3' y '4'.

Comparaciones encadenadas editar

Raku permite "encadenar" las comparaciones. Es decir, se permite una secuencia de comparaciones como la siguiente:

if 20 <= $temperatura <= 25 {
    say "¡La temperatura de la habitación está entre 20 y 25!";
}

Esto se trata como si se realizara cada comparación, de izquierda a derecha, y el resultado es combinado lógicamente con la operación and.

Evaluación perezosa editar

Raku usa la técnica de la evaluación perezosa de listas que es una característica de algunos lenguajes de la programación funcional, como el lenguaje Haskell:[43]

@enteros = 0..Inf;  # enteros desde 0 al infinito

Este código no caerá intentando asignar una lista de tamaño infinito al array @enteros, ni se quedará colgado indefinidamente intentando expandir la lista si solo se seleccionan un número limitado de elementos.

Esto simplifica muchas tareas comunes en Raku incluyendo las operaciones de entrada/salida, transformaciones de lista y paso de parámetros.

Reunión editar

Relativo a la evaluación perezosa es la construcción de listas perezosas usando gather y take, comportándose un poco como los generadores en lenguajes como Icon o Python.

my $cuadrados = lazy gather for 0..Inf {
    take $_ * $_;
};

$cuadrados será una lista infinita de números cuadrados, pero la evaluación perezosa de gather asegura que los elementos solo se computan cuando sean accedidos.

Ensamblajes editar

Raku introduce el concepto de ensamblajes (junctions, en inglés): valores que son compuestos de otros valores.[43]​ En su forma más simple, los ensamblajes se crean combinando un conjunto de valores con los operadores de yuxtaposición:

# Ejemplo para ensamblaje | ("any"):
my $color = 'white';
unless $color eq 'white' | 'black' | 'gray' | 'grey' {
    die "Color printing not supported\n";
}

# Ejemplo para ensamblaje & ("all"):
my $password = 'secret!123';
if $password ~~ /<:alpha>/ & /<:digit>/ & /<:punct>/ {
    say "Su contraseña es razonablemente segura";
}

| indica un valor que es igual tanto a su izquierda o los argumentos de su derecha. & indica un valor que es igual tanto a su izquierda y los argumentos de la derecha. Estos valores se pueden utilizar en cualquier código que utilice un valor normal. Las operaciones realizadas en un ensamblaje es para todos los miembros de la unión por igual, y combinan de acuerdo con el operador de yuxtaposición. Así, ("manzana"|"plátano") ~ "s" se convertirá en "manzanas"|"plátanos". En las comparaciones, los ensamblajes devuelven un único valor, verdadero o falso. El ensamblaje "any" devuelve verdadero si la comparación es cierta para alguno de los elementos del ensamblaje. El ensamblaje "all" devuelve verdadero si la comparación es cierta para todos los elementos del ensamblaje.

Los ensamblajes se pueden usar también para enriquecer el sistema de tipificado introduciendo un estilo de programación genérica, que se ajusta por los tipos de los ensamblajes:

subset Color of Any where RGB_Color | CMYK_Color;
sub obtener_tinta(Color $color, Num $opacidad) {
    ...
}

Macros editar

En lenguajes de bajo nivel, el concepto de macro ha llegado a ser sinónimo de sustitución de texto en el código fuente debido al amplio uso del preprocesador de C. En cambio, los lenguajes de alto nivel como Lisp anteceden a C en el uso de macros y de forma mucho más poderosa.[44]​ Raku se aprovechará de este concepto de macros del Lisp.[32]​ El poder de esta forma de macros deriva del hecho de que opera en el programa como una estructura de datos de alto nivel, en lugar de ser un texto simple, y con todas las capacidades del lenguaje de programación a su disposición.

Una definición de macro en Raku se parecerá a una definición de una subrutina o método y puede operar sobre: strings no analizadas, un árbol sintáctico representando código pre-analizado, o una combinación de los dos. Una definición de macro se parecería a esto::[45]

macro hola($que) {
    quasi { say "Hola { {{{$que}}} }" };
}

En este ejemplo particular, la macro no es más compleja que una sustitución al estilo del C, pero como el análisis del parámetro de la macro ocurre antes de que la macro opere sobre el código que la llama, los mensajes de diagnóstico serán mucho más informativos. En cambio, debido a que el cuerpo de la macro se ejecuta en tiempo de compilación cada vez que se la usa, se pueden emplear muchas técnicas de optimización. Es incluso posible eliminar enteramente cálculos complejos de los programas resultantes realizando el trabajo durante el tiempo de compilación.

Identificadores editar

En Perl, los nombres de los identificadores pueden usar los caracteres ASCII alfanuméricos y guiones bajos disponibles en otros lenguajes. En Raku, los alfanuméricos pueden incluir la mayor parte de los caracteres Unicode. Además, se pueden usar guiones y apóstrofes (con ciertas restricciones, tales como que estén seguidos por un dígito). Usar guiones en lugar de guiones bajos para separar palabras en un nombre se llama estilo de codificación “kebab”.

Ejemplos editar

Hola mundo editar

El programa hola mundo es un programa común usado para introducir un lenguaje. En Raku se puede escribir como

say 'Hola mundo';

Aunque en Perl "hay más de una forma de hacerlo".

Factorial editar

La función factorial en Raku, definida de varias formas:

# Usando recursión (con una construcción `if\else`)
sub fact( UInt $n --> UInt ) {
    if $n == 0 { 1 }
    else       { $n * fact($n-1) }
}

# Usando recursión (con `if` como modificador de sentencia)
sub fact( UInt $n --> UInt ) {
    return 1 if $n == 0;
    return $n * fact($n-1);
}

# Usando recursión (con una construcción `when`)
sub fact( UInt $n --> UInt ) {
    when $n == 0 { 1 }
    default      { $n * fact($n-1) }
}

# Usando el operador ternario
sub fact( UInt $n --> UInt ) {
    $n == 0 ?? 1 !! $n * fact($n-1)
}

# Usando despacheo múltiple
multi fact(0) { 1 }
multi fact( UInt $n --> UInt ) {
    $n * fact($n - 1)
}

# Usando el metaoperador de reducción
multi fact( UInt $n --> UInt ) {
    [*] 1..$n
}

# Crear un operador de factorial y usar el metaoperador de reducción
sub postfix:<!>( UInt $n --> UInt ) { [*] 1..$n }

# Usando el declarador `state` para crear un factorial memorizado
sub fact( UInt $n --> UInt ) {
    state %known = 0 => 1;
    return %known{$n} if %known{$n}:exists;
    %known{$n} = $n * fact($n-1);
    return %known{$n};
}

Quicksort editar

Quicksort es un conocido algoritmo de ordenación. Una implementación funcional usando el paradigma de la programación funcional se puede escribir en Raku:

# La lista vacía se ordena como lista vacía
multi quicksort([]) { () }

# De otra forma, se extrae el primer elemento como el pivote...
multi quicksort([$pivote, *@resto]) {

    # Partición
    my @antes = @resto.grep(* before $pivote);
    my @luego = @resto.grep(* after  $pivote);

    # Ordena las particiones
    flat (quicksort(@antes), $pivote, quicksort(@luego))
}

Torres de Hanói editar

Las Torres de Hanói se usa a menudo en la ciencia de la computación para enseñar la programación recursiva. Esta implementación usa los mecanismos de despacho múltiple y restricciones paramétricas de Raku.

multi sub hanoi(0, $, $, $) { }                         # No hay disco, no hacemos nada
multi sub hanoi($n, $a = 'A', $b = 'B', $c = 'C') {     # Empezar con $n discos y tres clavijas: A, B, C
    hanoi $n - 1, $a, $c, $b;                           # Primero mover los primeros $n - 1 discos de A a B
    say "Mover disco $n de clavija $a a clavija $c";    # Entonces mover último disco de A a C
    hanoi $n - 1, $b, $a, $c;                           # Al final, mover $n - 1 discos de B a C
}

Libros editar

En la historia de Raku existen dos olas de escritura de libros. La primera ola sigue al anuncio inicial de Perl 6, en 2000. Esos libros reflejan el estado del diseño del lenguaje en ese momento, y contienen material que hoy en día es obsoleto. La segunda ola, que sigue al anuncio de la versión 1.0 en 2015, incluye un libro que ya estaba publicado, y diversos libros que se están escribiendo.

Libros publicados antes de Perl 6 versión 1.0 editar

También, un libro dedicado a una de las primeras máquinas virtuales de Perl 6, Parrot, que se publicó en 2009.

Libros publicados después de Perl 6 versión 1.0 (conocida como versión 6.c) editar

Libros publicados con el nuevo nombre Raku editar

Libros que se publicarán editar

Existen informes de diferentes autores[46]​ sobre la aparición de nuevos libros que se publicarán pronto, todos ellos basados en la versión actual 1.0 (conocida como versión 6.c) de Perl 6.

Referencias editar

  1. a b Joab, Jackson (23 de julio de 2010). «Perl creator hints at imminent release of long-awaited Perl 6». IDG News Service. Consultado el 8 de febrero de 2015. 
  2. «Modules». Consultado el 19 de agosto de 2022. 
  3. «Announce: Raku Perl 6 'Diwali' 6.d Language Specification Release». blogs.perl.org. 5 de noviembre de 2018. Consultado el 19 de agosto de 2022. 
  4. «Glossary of Terms and Jargon». Perl Foundation Perl 6 Wiki. The Perl Foundation. 28 de febrero de 2011. Archivado desde el original el 21 de enero de 2012. Consultado el 8 de febrero de 2015. 
  5. a b 唐鳳, a.k.a. Audrey Tang (21 de abril de 2010). «How to Implement Perl 6 in '10». 
  6. «About Perl». perl.org. Consultado el 11 de junio de 2020. «"Perl" is a family of languages, "Raku" (formerly known as "Perl 6") is part of the family, but it is a separate language which has its own development team. Its existence has no significant impact on the continuing development of "Perl".» 
  7. «Perl 6 renamed to Raku». LWN.net. 15 de octubre de 2019. Consultado el 16 de octubre de 2019. 
  8. «TPF response to Raku rename». 29 de octubre de 2019. 
  9. Biancuzzi, Federico; Warden, Shane (2009). Masterminds of Programming: Conversations with the Creators of Major Programming Languages. ISBN 978-0596515171. 
  10. Kline, Joe (21 de agosto de 2000). «Report from the Perl Conference». 
  11. Wall, Larry (2000). «State of the Onion 2000». O'Reilly Network. 
  12. The Perl Foundation (2000). «About Perl6 RFCs». 
  13. Wall, Larry (2 de abril de 2001). «Apocalypse 1: The Ugly, the Bad, and the Good». 
  14. «Raku test suite». GitHub. 2019. 
  15. Larry Wall and the Perl 6 designers (2015). «Perl 6 Design Documents». 
  16. The Perl Foundation (2001). «Exegeses». 
  17. The Raku Programming Language (2022). «Raku Community». 
  18. «Raku». Github. Consultado el 19 de agosto de 2022. 
  19. a b Larry Wall. [url=https://design.raku.org/S01.html «Synopsis 1: Overview»]. Consultado el 10 de agosto de 2004.  (en inglés)
  20. «rakudo/rakudo - GitHub». Github.com. Consultado el 21 de septiembre de 2013. 
  21. Michaud, Patrick (16 de enero de 2008). «The compiler formerly known as 'perl6'». Archivado desde el original el 26 de noviembre de 2015. 
  22. Worthington, Jonathan (31 de mayo de 2013). «MoarVM: A virtual machine for NQP and Rakudo». Consultado el 24 de julio de 2013. 
  23. «MoarVM». MoarVM team. Consultado el 8 de julio de 2017. 
  24. «Feature comparison of Perl 6 compilers». Archivado desde el original el 7 de febrero de 2019. 
  25. Wall, Larry (2007). «Perl 6 STD». GitHub. 
  26. «mp6/kp6 FAQ». Perl 6 development team. 2006. Archivado desde el original el 26 de noviembre de 2015. 
  27. «Yapsi README». GitHub. 2011. 
  28. O'Rear, Stefan (29 de noviembre de 2011). «Niecza README.pod». GitHub. Consultado el 12 de enero de 2012. 
  29. Wall, Larry (2004). «Synopsis 11 : Modules». 
  30. «Raku Modules Directory». Modules.raku.org. Consultado el 17 de mayo de 2020. 
  31. a b Larry Wall. «Synopsis 2: Bits and Pieces». Consultado el 20 de mayo de 2009.  (en inglés)
  32. a b c Larry Wall. «Synopsis 6: Subroutines». Consultado el 21 de marzo de 2003.  (en inglés)
  33. a b Wall, Larry (20 de mayo de 2009). «Synopsis 4: Blocks and Statements». 
  34. Larry Wall. «Synopsis 12: Objects».  (en inglés)
  35. The Software Composition Group (2003). «Traits». Archivado desde el original el 11 de agosto de 2006. Consultado el 22 de septiembre de 2006. 
  36. Jonathan Worthington (2009). «Day 18: Roles». 
  37. chromatic (2009). «The Why of Perl Roles». 
  38. «Object orientation». docs.raku.org. Consultado el 24 de octubre de 2019. 
  39. Parlante, Nick (2000). «Essential Perl: String Processing with Regular Expressions». 
  40. Christiansen, Tom (1996). «PERL5 Regular Expression Description». Archivado desde el original el 31 de marzo de 2010. Consultado el 25 de marzo de 2010. «Perl's regexps "aren't" -- that is, they aren't "regular" because backreferences per sed and grep are also supported, which renders the language no longer strictly regular». 
  41. Wall, Larry (20 de mayo de 2009). «Synopsis 5: Regexes and Rules». 
  42. Larry Wall. «Apocalypse 5: Pattern Matching». Consultado el 4 de junio de 2002.  (en inglés)
  43. a b Larry Wall. «Synopsis 9: Data Structures». Consultado el 13 de septiembre de 2004.  (en inglés)
  44. Lamkins, David B. (8 de diciembre de 2004). «Capítulo 20». En bookfix.com, ed. Successful Lisp: How to Understand and Use Common Lisp. Archivado desde el original el 12 de septiembre de 2006. Consultado el 13 de septiembre de 2006.  (en inglés)
  45. «Macros». 
  46. Relación de libros sobre Perl 6

Enlaces externos editar