x
1

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.

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,[9]​ por Larry Wall, en su charla State of the Onion 2000.[10]​ 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.[11]

Una vez que el proceso de las RFC se completó, Wall revisó y clasificó cada petición. Empezó entonces el proceso de escribir los "Apocalipsis", un término que se refiere a la "revelación".[12]​ 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[13]​, mientras que las Sinopsis se mantienen como referencia histórica.[14]

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.[15]

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 en los servidores de The Perl Foundation en perl.org.[16]​ El tercero es el repositorio de código fuente Git alojado en https://github.com/raku.

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.

A lo largo de los años, Raku ha sufrido varias alteraciones en su dirección. De forma temprana se introdujeron conceptos desde Python y Ruby, pero a resultas de la aparición de Pugs -el primer intérprete capaz de ejecutar Raku- escrito en el lenguaje de programación Haskell, el equipo de diseño de Raku absorbió muchas influencias de la programación funcional.

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.

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".[17]

Rakudo Perl 6[18][19]​ 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[20]​ y la cadena de montaje del compilador NQP.[21]​ 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.

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.[22]

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.[23][24]​ 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.[25]

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.[26]

La especificación de Raku solicita que los módulos se identifiquen por nombre, versión y autoría.[27]​ 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.[28]

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 principal, pero no técnica, diferencia entre Perl y Raku es que Raku comienza como una especificación.[17]​ 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. 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.

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

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:

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.

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.[30]​ En Raku, una declaración de subrutina se parece a algo como esto:

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.

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:

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.

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.[31]

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).[30]

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

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:[29]

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

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:

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:

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.[32]​ Por ejemplo, una clase para encapsular un punto de coordenadas cartesianas se puede definir y utilizar de esta manera:

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 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[33]​ en la variante Squeak de Smalltalk. Son como las clases, pero ofrecen un mecanismo de composición más seguro.[34]​ 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.[35]

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.[36]

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.

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.

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.

Las expresiones regulares y el procesado de texto de Perl han sido siempre unas de sus características definitorias.[37]​ 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,[38]​ 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[39]​ 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'".[40]

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:[31]

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

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

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

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.

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:[41]

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.

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.

$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.

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

| 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:

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.[42]​ Raku se aprovechará de este concepto de macros del Lisp.[30]​ 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::[43]

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.

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”.

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

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

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

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:

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.

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.

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

Existen informes de diferentes autores[44]​ 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.



Escribe un comentario o lo que quieras sobre Perl 6 (directo, no tienes que registrarte)


Comentarios
(de más nuevos a más antiguos)


Aún no hay comentarios, ¡deja el primero!