Parallel Specification and Implementation Language ( ParaSail ) es un lenguaje de programación paralela orientado a objetos . Su diseño y su implementación en curso se describen en un blog [2] y en su sitio web oficial. [3]
ParaSail utiliza un modelo de programación sin punteros , donde los objetos pueden crecer y encogerse, y se utiliza la semántica de valores para la asignación. No tiene un montón de recolección de basura global . En su lugar, se utiliza una gestión de memoria basada en regiones en todo momento. Los tipos pueden ser recursivos, siempre que los componentes recursivos se declaren como opcionales . No hay variables globales, ni alias de parámetros, y todas las subexpresiones de una expresión se pueden evaluar en paralelo. Las afirmaciones , precondiciones , poscondiciones , invariantes de clase , etc., son parte de la sintaxis estándar , utilizando una notación similar a Hoare . Cualquier posible condición de carrera se detecta en tiempo de compilación .
El diseño inicial de ParaSail comenzó en septiembre de 2009, por S. Tucker Taft.
Hay disponibles tanto un intérprete que utiliza la máquina virtual ParaSail como un compilador ParaSail basado en LLVM . Se utiliza el robo de trabajo para programar los subprocesos livianos de ParaSail . La última versión se puede descargar desde el sitio web de ParaSail. [3]
La sintaxis de ParaSail es similar a Modula , pero con un modelo de programación orientado a objetos basado en clases e interfaces más similar a Java o C# .
Más recientemente, las construcciones paralelas de ParaSail se han adaptado a otras sintaxis, para producir lenguajes paralelos similares a Java , Python y Ada , denominados, respectivamente, Javallel, Parython y Sparkel (nombrado así por el subconjunto de Ada SPARK en el que se basa). Los compiladores e intérpretes para estos lenguajes se incluyen con la implementación de ParaSail. [3]
El siguiente es un programa Hola mundo en ParaSail:
func Hola_Mundo ( var IO ) es IO . Println ( "Hola, Mundo" ); fin func Hola_Mundo ;
La siguiente es una interfaz para un módulo de mapa básico:
interfaz BMap < Key_Type es Ordered <>; Element_Type es Assignable < >> es op "[]" () - > BMap ; // Crea un mapa vacío func Insertar ( var BMap ; Clave : Tipo_de_clave ; Valor : Tipo_de_elemento ); func Buscar ( BMap ; Clave : Tipo_de_clave ) - > opcional Tipo_de_elemento ; func Eliminar ( var BMap ; Clave : Tipo_de_clave ); func Contar ( BMap ) - > Univ_Integer ; fin de la interfaz BMap ;
A continuación se muestra una posible implementación de este módulo de mapa, utilizando un árbol binario:
La clase BMap es interfaz Binary_Node <> es // Un módulo de nodo binario "concreto" simple var Left : Binary_Node opcional ; var Right : Binary_Node opcional ; const Key : Key_Type ; var Value : Element_Type opcional ; // nulo significa eliminado fin interfaz Binary_Node ; var Árbol : nodo binario opcional ; var Conteo := 0 ; Exportaciones op "[]" () - > BMap es // Crea un mapa vacío return ( Tree => null , Count => 0 ); fin op "[]" ; func Insert ( var BMap ; Key : Key_Type ; Value : Element_Type ) es // Buscar Key, sobrescribir si se encuentra, insertar nuevo nodo si no es para M => BMap . Loop de árbol si M es nulo entonces // No está ya en el mapa; agregarlo M := ( Key => Key , Value = > Value , Left => null , Right => null ); BMap . Count += 1 ; else case Key = ? M. Key of [ #less ] => continuar loop con M. Left ; [ #greater ] => continuar loop con M. Right ; [ #equal ] => // Key ya está en el mapa; // recuento de golpes si Value era nulo; si M. Value es nulo entonces BMap . Count += 1 ; fin si ; // en cualquier caso sobrescribir el campo Value M. Value : = Value ; retorno ; fin del caso ; fin si ; fin del bucle ; fin func Insert ; func Find ( BMap ; Key : Key_Type ) - > opcional Element_Type es // Buscar clave, devolver el valor asociado si está presente o nulo en caso contrario para M => BMap . Tree while M not null loop case Key =? M . Key of [ #less ] => continuar el bucle con M . Left ; [ #greater ] => continuar el bucle con M . Right ; [ #equal ] => // Lo encontré; devolver el valor return M . Value ; fin del caso ; fin del bucle ; // No se encontró en BMap return null ; fin func Find ; func Delete ( var BMap ; Key : Key_Type ) es // Buscar clave; eliminar el nodo asociado si se encuentra para M => BMap . Tree while M not null loop case Key = ? M. Key of [ #less ] => continuar el bucle con M. Left ; [ #greater ] => continuar el bucle con M. Right ; [ #equal ] => // Lo encontró; si como máximo un subárbol no es nulo, sobrescríbalo ; de lo contrario, establezca su campo de valor en nulo // ( para evitar un reequilibrio más complejo). if M. Left es nulo then // Mover el subárbol derecho a M M <== M. Right; elsif M. Right es nulo then // Mover el subárbol izquierdo a M M < == M. Left ; else // No se puede reclamar el nodo inmediatamente; // establecer el campo de valor en nulo en su lugar. M. Value : = null ; end if ; // Decrementar el conteo BMap . Count - = 1 ; end case ; fin del bucle ; // No se encontró en el mapa fin de función Eliminar ; func Count ( BMap ) - > Univ_Integer es // Devuelve el recuento de la cantidad de elementos en el mapa return BMap . Count ; fin de función Count ;fin de la clase BMap ;
A continuación se muestra un programa de prueba simple para el módulo BMap:
import PSL :: Core :: Random ; import BMap ; func Test_BMap ( Num : Univ_Integer ; Seed : Univ_Integer ) es // Probar el mapa basado en árbol binario var Ran : Random := Start ( Seed ); // Iniciar una secuencia de números aleatorios // Declarar un mapa de números enteros a cadenas var M : BMap < Key_Type => Univ_Integer , Element_Type => Univ_String >; M := []; // Inicializa el mapa en el mapa vacío para I en 1 .. Num * 2 bucle hacia adelante // Agregar elementos al mapa const Key := Next ( Ran ) mod Num + 1 ; const Val := "Val" | To_String ( I ); Println ( "A punto de insertar " | Key | " => " | Val ); Insertar ( M , Key , Val ); fin del bucle ; Println ( "Count = " | Count ( M )); para I en 1 .. Num loop // Buscar elementos en el mapa const Key := Next ( Ran ) mod Num + 1 ; Println ( "Buscando " | Key | ", encontrado " | Find ( M , Key )); fin del bucle ; para I en 1 .. Num / 3 bucle // Eliminar algunos elementos del mapa const Key := Next ( Ran ) mod Num + 1 ; Println ( "A punto de eliminar " | Key ); Delete ( M , Key ); fin del bucle ; Println ( "Count = " | Count ( M )); para I en 1 .. Num bucle hacia adelante // Buscar nuevamente elementos en el mapa Println ( "Buscando " | I | ", encontrado " | Find ( M , I )); fin del bucle ; fin función Test_BMap ;