Raku (lenguaje de programación)

De Wikipedia, la enciclopedia libre
Esta es una versión antigua de esta página, editada a las 23:57 8 nov 2014 por CEM-bot (discusión · contribs.). La dirección URL es un enlace permanente a esta versión, que puede ser diferente de la versión actual.
Perl 6
Desarrollador(es)
Comunidad Perl
https://raku.org/ y https://perl6.org/
Información general
Extensiones comunes .pl, .pm, .pod
Paradigma multiparadigma: orientado a objetos, imperativo, funcional, reflexivo
Apareció en 2000
Diseñado por Larry Wall
Última versión estable (varía según la implementación)
Rakudo Star / 26 de septiembre de 2014 (9 años, 7 meses y 25 días)[1]
Niecza Perl 6 / 26 de marzo de 2013 (11 años, 1 mes y 26 días)[2]
Sistema de tipos dinámico, estático, gradual
Implementaciones Rakudo Star, Niecza
Influido por Haskell,[3]JavaScript, Perl 5, Ruby, Smalltalk
Sistema operativo Multiplataforma
Licencia GPL o Licencia Artística

Perl 6 es un miembro de la familia de lenguajes de programación Perl.[4]​ Todavía está en desarrollo, como una especificación sobre la que se han escrito varios intérpretes y compiladores. Está incorporando elementos de muchos lenguajes modernos e históricos. Perl 6 está destinado a tener muchas implementaciones. La compatibilidad con versiones anteriores de Perl no es un objetivo directo, aunque un modo de compatibilidad es parte de la especificación. El proceso de diseño de Perl 6 comenzó en el 2000.

El desarrollo de Pugs, la primera implementación con mayor empuje, comenzó en el 2005, y hoy existen múltiples proyectos de implementación de Perl 6. Rakudo Perl 6 está basado en Parrot y NQP (Not Quite Perl), y aparecen nuevas versiones cada mes. En julio de 2010, el proyecto lanzó la primera distribución Rakudo Star,[5]​ una colección de útiles y materiales relacionados, de una implementación de Perl 6. Larry Wall mantiene una referencia de la gramática conocida como STD.pm, escrita en Perl 6 y ejecutada con Perl 5.

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

Historia

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

El proceso de diseño de Perl 6 fue anunciado por primera vez el 19 de julio de 2000, en el cuarto día de la Conferencia Perl anual,[7]​ por Larry Wall, en su charla State of the Onion 2000.[8]​ 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 los 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.[9]

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".[10]​ 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 previos iban siendo invalidados por los cambios 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 Perl 6 continua casi de forma completa dentro de las Sinopsis.[11]

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

A día de hoy, se usan tres métodos de comunicación en el desarrollo de Perl 6. El primero es el canal de IRC #perl6. El segundo es un conjunto de listas de correo en los servidores de The Perl Foundation en perl.org.[13]​ El tercero es el repositorio de código fuente Git alojado en https://github.com/perl6.

Objetivos

La ruptura en la compatibilidad era obligada desde el comienzo del proyecto, e inmediatamente permitió algunos de los cambios que Larry Wall había sugerido en su discurso inicial. "Verrugas históricas" tales como la confusión que rodea el uso del sigilo (sigil) para los contenedores; la ambigüedad entre las funciones select; el impacto sintáctico de los gestores de fichero de una simple palabra; y muchos otros problemas que los programadores de Perl habían discutido cómo arreglar durante años fueron algunos de los primeros temas tratados.

A lo largo de los años, Perl 6 ha sufrido varias alteraciones en su dirección. De forma temprana se introdujeron conceptos desde Python y Ruby, pero a resultas de la escritura del intérprete Pugs en el lenguaje de programación Haskell, muchas influencias de la programación funcional fueron absorbidas por el equipo de diseño de Perl 6.

Mascota

El nombre de la mascota es "Camelia, el bicho de Perl 6".[14]​ Su nombre es una referencia a la mascota del camello arábigo asociado a Perl, y su forma, siguiendo la tradición amorosa de la comunidad Perl, es una reproducción de un "error de software". Diseños simétricos incrustados en sus alas recuerdan las letras "P6", la abreviatura de Perl 6.

Implementaciones

En 2014, múltiples implementaciones de Perl 6 están bajo desarrollo, pero ninguna de ellas se puede considerar "completa". Como se ha indicado en la sección Historia el diseño del lenguaje sigue estando sujeto a cambio. Ninguna implementación será designada como la oficial de Perl 6; en su lugar, "Perl 6 será cualquier cosa que pase el conjunto de test oficial".[15]

Rakudo Perl[16][17]​ es una implementación de Perl 6 para diversas máquinas virtuales, como JVM, MoarVM, Javascript y la Máquina virtual Parrot. Parrot es una máquina virtual diseñada para lenguajes de programación dinámicos, principalmente para Perl 6. Posee diversas y poderosas herramientas de compilación, muchas de ellas inspiradas por Perl 6. En particular, el Parser Grammar Engine, o PGE, ofrece una implementación de las gramáticas de Perl 6. También, el lenguaje utilizado para construir compiladores es el Not Quite Perl 6, o NQP. La implementación Rakudo de Perl 6 sobre Parrot toma lo mejor de PGE y NQP. La mayor parte de Rakudo ha sido escrito en el mismo Perl 6, 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 es una implementación de Perl 6 escrito en el lenguaje de programación Haskell. Pugs puede ejecutar código Perl 6 directamente, así como compilar Perl 6 a JavaScript, Perl 5 o bytecode de Parrot. Pugs es utilizado como la implementación más avanzada de Perl 6, pero desde mediados del 2007 está prácticamente dormido (solo han aparecido actualizaciones para las nuevas versiones de GHC, desde entonces).

v6.pm es una implementación de Perl 6 en puro Perl 5, haciendo un uso liberal de módulos actuales de CPAN, como el Moose y el Pugs::Compiler::Rule. Su ánimo es hacer del actual intérprete Perl la principal máquina virtual tanto para Perl 5 como para Perl 6.[18]

En 2007, v6-MiniPerl6 ("mp6") y su reimplementación, v6-KindaPerl6 ("kp6") fueron escritos como un medio para arrancar el Perl-6.0.0 STD, usando Perl 5. 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.[19][20]​ 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.

Sprixel ha sido escrito como un medio para arrancar el Perl 6.0.0 STD sobre el CLR, utilizando un nuevo lenguaje/entorno intermediario denominado Perlesque, que se propone aplicar de cerca el subconjunto de tipos fijos de Perl 6. Su repositorio de código fuente se encuentra en Google Code como CSMeta. CSMeta/Perlesque/Sprixel han evolucionado a partir del proyecto JSMeta/Sprixel en JavaScript, que se encuentra en Google Code y en el repositorio de pugscode.

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

Sistema de módulos

La especificación de Perl 6 solicita que los módulos queden identificados por nombre, versión y autoría.[22]​ Es posible cargar sólo 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 5, todavía no maneja módulos Perl 6. En su lugar, se usa un prototipo de un sistema de módulos.[23]

Principales cambios con respecto a Perl 5

Perl 5 y Perl 6 difieren fundamentalmente, aunque en general la intención es la de "mantener Perl 6 como Perl". La mayor parte de los cambios están dirigidos a normalizar el lenguaje, para hacerlo más fácil de aprender, que lo entiendan los programadores expertos y hacer "cosas fáciles más fácilmente y las difíciles, más posibles".

Una especificación

Una principal, pero no técnica, diferencia entre Perl 5 y Perl 6 es que Perl 6 comienza como una especificación.[15]​ Esto significa que, si es necesario, Perl 6 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 de Perl 5 está considerada como excelente,[24]​ incluso fuera de la comunidad Perl, donde incluso la mezcla de las críticas dan una idea de su madurez y amplitud. Sin embargo, la documentación no se considera autorizada, y sólo describe el comportamiento real del intérprete de Perl 5 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 5.

Un sistema tipificado

En Perl 6, el sistema de tipos de Perl 5 ha sido aumentado con la adición de tipos estáticos.[25]​ Por ejemplo:

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

Sin embargo, el tipificado 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

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

Lista formal de parámetros de subrutinas

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

Perl 6 presenta verdaderos parámetros formales al lenguaje.[26]​ En Perl 6, una declaración de subrutina se parece a algo como esto:

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

Como en Perl 5, 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 son marcados como constantes por lo que no pueden ser modificados. Pueden ser declaradas explícitamente como alias de lectura-escritura del valor original o como copias usando 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

Perl 6 proporciona tres modos básicos de la transmisión de parámetros:

  • Posicional
  • Nombre
  • Absorbido

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 puede ser transmitido mediante el uso de su nombre en una manera desordenada. Un parámetro denominado con sólo su nombre sólo puede ser pasado especificando su nombre (es decir, nunca se captura un argumento posicional), y son indicados con un precedente carácter :. Parámetros absorbidos (indicados con un * antes del nombre del parámetro) son la herramienta de Perl 6 para la creación de funciones variadic. Un hash absorbido capturará los restantes pasados por nombre, mientras que un array absorbido 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)
 algunaFuncion(:b<2>, :a<1>); # $a="1", $b="2"

Los parámetros posicionales, como los indicados antes son siempre requeridos, a no ser que sean seguidos por ? para indicar que son opcionales. Los parámetros con nombre son opcionales por defecto, pero puede ser marcados como requeridos con la adición de ! después del nombre de la variable. Parámetros absorbidos son siempre opcionales.

Bloques y clausuras

Los parámetros también se pueden pasar a bloques arbitrarios, que actúan como clausuras. Así es como, por ejemplo, los iteradores de los bucles for y while son indicados. 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.[27]

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

Invarianza del sigilo

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

# Perl 5
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 Perl 6, 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:[25]

# Perl 6
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 5 fue inspirada 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 pueden requerir una expresión tanto en forma singular como plural, en un solo término:

 # Perl 5: 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. Comparar con Perl 6:

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

Programación orientada a objetos

Perl 5 soporta Programación orientada a objetos mediante un mecanismo conocido como bendición. Cualquier referencia puede ser bendecida 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 -prácticamente cualquier otro lenguaje de programación puede simular este modelo de objetos usando esta simple técnica- 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", Perl 6 mantiene el modelo de la bendición, y proporciona un modelo de objetos más sólido para los casos comunes.[28]​ Por ejemplo, una clase para encapsular un punto de coordenadas cartesianas puede ser definido y utilizado de esta manera:

 class Punto is rw {
   has $.x;
   has $.y;
 }
 
 my $punto = Punto.new( x => 1.2, y => -3.7 );
 
 # Ahora cambiamos x (note el método "x" usado como valor a la izquierda):
 $punto.x = 2;
 say "Punto está en la posición X: ", $punto.x;

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 Perl 6, $.x es llamado un "atributo". Algunos lenguajes llaman a esto campos o miembros. El método utilizado para acceder a un atributo es llamado un descriptor de acceso. Los auto-accesores son métodos que son creados automáticamente, como el método x del ejemplo anterior. 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 auto-accesor puede serle pasado un nuevo valor para establecer el atributo, o puede ser asignado directamente como un valor a la izquierda (como en el ejemplo). Auto-accesores pueden ser sustituidos 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 sólo se puede acceder directamente desde dentro de una definición de clase. Todos los demás accesos deben hacerse a través de los métodos de acceso.

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

Roles

Roles en Perl 6 toman la función de las interface en Java, mixins en Ruby, y rasgos[29]​ en la variante Squeak de Smalltalk. Son como las clases, pero son completamente abstractas. Se utilizan para realizar composición con otras clases en lugar de añadirse como en la cadena de herencia. 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 son instanciables; los roles, no.[30]

En esencia, un rol es un conjunto de (posiblemente abstracto) 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, Perl 6 creará una subclase anónima, agregará el rol a la subclase, y cambiará la clase del objeto a la subclase anónima.

Por ejemplo, un Perro es un Mamífero. Perro heredan ciertas características de los mamíferos, como las glándulas mamarias y (a través de los antecedentes de los mamíferos, los Vertebrados) una espalda. Los Perros pueden tener uno de varios tipos distintos de comportamiento; por ejemplo, un Perro puede ser una Mascota, a asilvestrarse, o ser Perro_guía para los ciegos. Sin embargo, estos son simplemente conjuntos de comportamientos adicionales que se pueden agregar a un Perro; un Gato también puede ser doméstico o silvestre, por ejemplo. Por lo tanto, Perro y Mamífero son clases, mientras Mascota, Silvestre, y Perro_guía son roles.

 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, a diferencia de la de herencia 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

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

Perl 6 ofrece un superconjunto de las posibilidades de Perl 5 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[33]​ Las Reglas se presentan con la palabra clave rule que tiene un uso muy similar a la definición de subrutinas. Reglas anónimas pueden ser definidas con la palabra clave regex (o rx), o pueden simplemente usarse incluidas como las expresiones regulares donde en Perl 5 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'".[34]

Simplificación sintáctica

Algunas construcciones de Perl 5 han sido cambiadas en Perl 6, 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 5 ahora son opcionales:[27]

 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

Perl 6 permite "encadenar" las comparaciones. Es decir, una secuencia de comparaciones como las siguientes:

 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

Perl 6 usa la técnica de la evaluación perezosa de listas que ha sido una característica de algunos lenguajes de la programación funcional, como el lenguaje Haskell:[35]

 @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 sólo se seleccionan un número limitado de elementos.

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

Reunión

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 = 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 son solo computados cuando sean accedidos.

Ensamblajes

Perl 6 introduce el concepto de ensamblajes (junctions, en inglés): valores que son compuestos de otros valores.[35]​ En los primeros días del diseño de Perl 6, se les llamó "superposiciones", por analogía con el concepto superposición cuántica de la Mecánica cuántica —formas de onda que simultáneamente ocupan varios estados hasta que el observador los "colapsa". Un módulo Perl 5 lanzado en el 2000 por Damian Conway llamado Quantum::Superpositions[36]​ ofrece una inicial prueba de concepto. Mientras que al principio, valores superpuestos parecen meramente como una curiosidad de la programación, con el tiempo se ha reconocido su utilidad e intuición siendo ampliamente reconocido y los ensamblajes ahora ocupan un lugar central en el diseño de Perl 6.

En su forma más simple, los ensamblajes son creados combinando un conjunto de valores con los operadores de yuxtaposición:

 my $digito_par    = 0 | 2 | 4 | 6 | 8; # any(0, 2, 4, 6, 8)
 my $digitos_impar = 1 & 3 & 5 & 7 & 9; # all(1, 3, 5, 7, 9)

| 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 pueden ser usados también para enriquecer el sistema de tipificado introduciendo un estilo de programación genérica, que es ajustada por los tipos de los ensamblajes:

 sub obtener_tinte(RGB_Color | CMYK_Color $color, Num $opacidad) {
     . . .
 }
 sub almacenar_registro(Registro & Almacen $reg) {
     . . .
 }

Autohilado

Los ensamblajes están desordenados; 1|2|3 y 3|2|1 representan el mismo valor. Esta falta de ordenación significa que el compilador de Perl 6 puede elegir evaluar expresiones de ensamblajes en paralelo. Por ejemplo, el código

if $string ~~ all(@list_of_regexes) {
   ...
}

indicaría al compilador que todas las coincidencias de una cadena contra una lista de expresiones regulares puede ser ejecutada en paralelo, posiblemente en hilos separados. Esta característica se llama autothreading; su uso e implementación no está finalizada y es materia de debate en la comunidad de desarrollo.[37]​ La paralelización del autohilado no está implementada todavía en ninguno de los compiladores de Perl 6.[38]

Macros

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.[39]​ Perl 6 se aprovechará de este concepto de macros del Lisp.[26]​ 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 Perl 6 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::[40]

 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.

Ejemplos

Hola mundo

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

 say 'Hola mundo'

aunque en Perl "hay más de una forma de hacerlo". La función say imprime sus argumentos, como la función print, pero añadiendo un carácter de nueva línea (esta característica fue portada a Perl v5.10).

Quicksort

Quicksort es un conocido algoritmo de ordenación. Una implementación funcional usando el paradigma de la programación funcional puede ser, suficientemente, escrito en Perl 6:

 # La lista vacía se ordena en la lista vacía
 multi quicksort([]) { () }
 
 # De otra forma, extrae el primer elemento como el pivote...
 multi quicksort([$pivote, *@resto]) {
     # Partición
     my @antes = @resto.grep(* <  $pivote);
     my @luego = @resto.grep(* >= $pivote);
 
     # Ordena las particiones
     (quicksort(@antes), $pivote, quicksort(@luego))
 }

Torres de Hanói

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 Perl 6.

 multi sub hanoi(0, $, $, $) { }                         # No 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
 }

Referencias

  1. «Rakudo Star 2014.09». 26 de septiembre de 2014. Consultado el 11 de octubre de 2014. 
  2. «Niecza Perl 6 v16». 
  3. «Glossary of Terms and Jargon». Perl Foundation Perl 6 Wiki. The Perl Foundation. 28 de febrero. Consultado el 9 de febrero de 2012. 
  4. «About Perl». perl.org. Consultado el 20 de abril de 2013. «"Perl" is a family of languages, "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 5".» 
  5. Michaud, Patrick (29 de julio de 2010). «Announce: Rakudo Star - a useful, usable, "early adopter" distribution of Perl 6». Consultado el 12 de enero de 2012. 
  6. O'Rear, Stefan (29 de noviembre de 2011). «Niecza README.pod». Consultado el 12 de enero de 2012. 
  7. Kline, Joe (2000-08-21). «Report from the Perl Conference». 
  8. Wall, Larry (2000). «State of the Onion 2000». O'Reilly Network. 
  9. The Perl Foundation (2000). «About Perl6 RFCs». 
  10. Wall, Larry (2 de abril de 2001). «Apocalypse 1: The Ugly, the Bad, and the Good». 
  11. The Perl Foundation (2002). «Perl Development: Synopses». 
  12. The Perl Foundation (2001). «Exegeses». 
  13. The Perl Foundation (2002). «Perl Development: Mailing Lists». 
  14. Joab, Jackson (23 de julio de 2010). «Perl creator hints at imminent release of long-awaited Perl 6». IDG News Service. Consultado el 30 de diciembre de 2013. 
  15. a b Larry Wall. [url=http://perlcabal.org/syn/S01.html «Synopsis 1: Overview»]. Consultado el 10 de agosto de 2004.  (en inglés)
  16. «rakudo/rakudo - GitHub». Github.com. Consultado el 21 de septiembre de 2013. 
  17. Michaud, Patrick (16 de enero de 2008). «The compiler formerly known as 'perl6'». 
  18. audreyt. «Pugs 6.2.12 and v6.pm released!». use Perl. 
  19. «mp6/kp6 FAQ». Perl 6 development team. 2006. 
  20. Wall, Larry, et al. (2007). «Perl 6 STD». 
  21. «Yapsi README». 2011. 
  22. Wall, Larry (2004). «Synopsis 11 : Modules». 
  23. http://modules.perl6.org/
  24. Lhotsky, Brad (10 de marzo de 2004). «Thinking In Perl». 
  25. a b Larry Wall. «Synopsis 2: Bits and Pieces». Consultado el 10 de agosto de 2004.  (en inglés)
  26. a b c Larry Wall. «Synopsis 6: Subroutines». Consultado el 21 de marzo de 2003.  (en inglés)
  27. a b Wall, Larry (20 de mayo de 2009). «Synopsis 4: Blocks and Statements». 
  28. Larry Wall. «Synopsis 12: Objects».  (en inglés)
  29. The Software Composition Group (2003). «Traits». 
  30. chromatic (2009). «The Why of Perl Roles». 
  31. Parlante, Nick (2000). «Essential Perl: String Processing with Regular Expressions». 
  32. Christiansen, Tom (1996). «PERL5 Regular Expression Description». «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». 
  33. Wall, Larry (20 de mayo de 2009). «Synopsis 5: Regexes and Rules». 
  34. Larry Wall. «Apocalypse 5: Pattern Matching». Consultado el 4 de junio de 2002.  (en inglés)
  35. a b Larry Wall. «Synopsis 9: Data Structures». Consultado el 13 de septiembre de 2004.  (en inglés)
  36. Damian Conway. «Quantum::Superpositions - QM-like superpositions in Perl».  (en inglés)
  37. «Autothreading specificication». 
  38. «Perl 6 feature matrix, section Concurrency».  (en inglés)
  39. Lamkins, David B. (8 de diciembre de 2004). http://psg.com/~dlamkins/sl/chapter20.html |urlcapítulo= sin título (ayuda). En bookfix.com, ed. Successful Lisp: How to Understand and Use Common Lisp.  (en inglés)
  40. «Macros». 

Enlaces externos