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]
Descripción
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]
Ejemplos
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 encuentra 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 de la función Test_BMap ;
Referencias
- ^ Rumpf, Andreas (19 de octubre de 2017). "Nim sin GC". Reflexiones de Araq . Consultado el 1 de septiembre de 2020 .
- ^ Blog de ParaSail
- ^ Sitio web de abc ParaSail
Referencias generales
- Graham-Rowe, Duncan (28 de julio de 2011). «Nuevo lenguaje para la programación en paralelo». Technology Review . MIT. Archivado desde el original el 26 de octubre de 2015 . Consultado el 18 de agosto de 2012 .
- Clarke, Peter (28 de julio de 2011). "SofCheck prepara el lenguaje paralelo ParaSail". EETimes . UBM Electronics.
- Taft, S. Tucker (9 de junio de 2012). "ParaSail: Menos es más con multinúcleo". EETimes . UBM Electronics.
- Selwood, Dick (18 de julio de 2012). "¿Necesita el mundo un nuevo lenguaje de programación?". EEJournal . techfocus media, inc.
Enlaces externos
- Sitio web oficial
- Blog del proceso de diseño e implementación
- Grupo de noticias sobre el idioma ParaSail