Oxygene (anteriormente llamado Chrome ) es un lenguaje de programación desarrollado por RemObjects Software para la Infraestructura de Lenguaje Común (CLI) de Microsoft , la plataforma Java y Cocoa . Oxygene se basa en el lenguaje Delphi Object Pascal y tiene influencias de C# , Eiffel , Java , F# y otros.
En comparación con Delphi.NET , ahora obsoleto , Oxygene no hace hincapié en la compatibilidad total con versiones anteriores , sino que está diseñado para ser una "reinvención" del lenguaje, aprovechando todas las características y tecnologías proporcionadas por los entornos de ejecución de máquinas virtuales .NET y Java .
Oxygene es un producto comercial que ofrece una integración completa con el entorno de desarrollo integrado (IDE) Visual Studio de Microsoft en Windows, y con su propio IDE llamado Fire para macOS . Oxygene es uno de los seis lenguajes compatibles con la cadena de herramientas del compilador Elements , junto con C# , Swift , Java , Go y Mercury (basado en Visual Basic (.NET) ).
Desde 2008 hasta 2012, RemObjects Software licenció su compilador y tecnología IDE a Embarcadero para que se utilizara como compilador de backend en su producto Embarcadero Prism. [ 2 ] A partir del otoño de 2011, Oxygene estuvo disponible en dos ediciones separadas, y la segunda edición agregó soporte para los entornos de ejecución de Java y Android. A partir del lanzamiento de XE4, Embarcadero Prism ya no forma parte de la SKU de RAD Studio. Existen numerosas rutas de soporte y actualización para que los clientes de Prism migren a Oxygene. [ 3 ] A partir de 2016, solo hay una edición de Oxygene, que permite el desarrollo en Windows o macOS, y que puede crear ejecutables para Windows, Linux, WebAssembly .NET, iOS, Android, Java y macOS.
El idioma
El lenguaje Oxygene tiene sus orígenes en Object Pascal en general y en Delphi en particular, pero fue diseñado para reflejar las directrices de la programación .NET y para crear ensamblados totalmente compatibles con CLR. Por lo tanto, algunas características menores del lenguaje conocidas de Object Pascal-Delphi se han eliminado o revisado, mientras que se han añadido muchas características nuevas y más modernas, como los genéricos o las secuencias y consultas.
Oxygene es un lenguaje de programación orientado a objetos . Por lo tanto, utiliza clases, que pueden almacenar datos y ejecutar código, para diseñar programas. Las clases son "prototipos" de objetos; por ejemplo, la idea de una manzana es el prototipo de la manzana que se puede comprar en una tienda. Se sabe que una manzana tiene color y que se puede pelar: estos son los datos y el "código" ejecutable de la clase manzana.
Oxygene ofrece soporte a nivel de lenguaje para algunas características de la programación paralela. El objetivo es utilizar todos los núcleos o procesadores de un ordenador para mejorar el rendimiento. Para lograrlo, las tareas deben distribuirse entre varios hilos. La clase del .NET FrameworkThreadPool ofrecía una forma de trabajar eficientemente con varios hilos. La biblioteca Task Parallel Library (TPL) se introdujo en .NET 4.0 para proporcionar más funcionalidades para la programación paralela.
En Oxygene, los operadores se pueden sobrecargar utilizando la siguiente class operatorsintaxis:
operador de clase implícito ( i : Entero ) : MiClase ;Tenga en cuenta que, para la sobrecarga de operadores, cada operador tiene un nombre que debe usarse en la sintaxis de sobrecarga de operadores, ya que, por ejemplo, "+" no sería un nombre de método válido en Oxygene. [ 4 ]
Estructura del programa
Oxygene no utiliza "Unidades" como Delphi, sino que emplea espacios de nombres .NET para organizar y agrupar tipos. Un espacio de nombres puede abarcar varios archivos (y ensamblados), pero un archivo solo puede contener tipos de un único espacio de nombres. Este espacio de nombres se define en la parte superior del archivo:
espacio de nombres AplicaciónConsola1;
Los archivos de Oxygene se dividen en una sección de interfaz y una sección de implementación, que es la estructura conocida de Delphi. La sección de interfaz sigue a la declaración del espacio de nombres. Contiene la usescláusula que, en Oxygene, importa tipos de otros espacios de nombres:
utiliza System.Linq ;Los espacios de nombres importados deben estar en el propio proyecto o en los ensamblados a los que se hace referencia. A diferencia de C#, en Oxygene no se pueden definir alias para los espacios de nombres, solo para nombres de tipos individuales (véase más abajo).
Tras la usescláusula, un archivo contiene declaraciones de tipo, como las que se conocen en Delphi:
interfaztipo ConsoleApp = clase pública método de clase Main ; fin ;Al igual que en C#, el método Main es el punto de entrada de cualquier programa. Puede tener un parámetro para pasar argumentos de línea de comandos al programa.args : Array of String
Se pueden declarar más tipos sin repetir la typepalabra clave.
La implementación de los métodos declarados se encuentra en la sección de implementación:
implementaciónMétodo de clase ConsoleApp.Main ; begin // agrega tu propio código aquí Console.WriteLine ( 'Hola Mundo .' ) ; end ;fin .Los archivos siempre terminan conend.
Tipos
Como lenguaje .NET, Oxygene utiliza el sistema de tipos de .NET : existen tipos de valor (como las estructuras) y tipos de referencia (como las matrices o las clases).
Aunque no introduce tipos "predefinidos" propios, Oxygene ofrece nombres genéricos más "pascalistas" para algunos de ellos, [ 5 ] de modo que, por ejemplo, se System.Int32puede usar como Integery Boolean( System.Boolean), Char( System.Char), Real( System.Double) también se unen a la familia de nombres de tipos pascalistas. El carácter de estructura de estos tipos, que es parte de .NET, se conserva completamente.
Como en todos los lenguajes .NET, los tipos en Oxygene tienen visibilidad. En Oxygene, la visibilidad predeterminada es assembly, que es equivalente a la internalvisibilidad en C#. La otra visibilidad de tipo posible es public.
tipo MyClass = clase pública fin ;La visibilidad se puede configurar para cada tipo definido (clases, interfaces, registros, ...).
Se puede definir un alias para los tipos, que se puede usar localmente o en otros ensamblados de Oxygene.
type IntList = public List < Integer >; //visible en otros ensamblados de Oxygene SecretEnumerable = IEnumerable < String >; //no visible en otros ensambladosLos alias de tipo público no serán visibles para otros idiomas.
Archivos
Los registros son como se denominan las estructuras .NET en Oxygene. Se declaran igual que las clases, pero con la recordpalabra clave:
tipo MyRecord = método de registro Foo ; fin ;Como son simplemente estructuras .NET, los registros pueden tener campos, métodos y propiedades, pero no tienen herencia y no pueden implementar interfaces .
Interfaces
Las interfaces son un concepto fundamental en el mundo .NET; el propio framework las utiliza ampliamente. Una interfaz especifica un pequeño conjunto de métodos, propiedades y eventos que una clase debe implementar al implementar dicha interfaz. Por ejemplo, la interfaz IEnumerable<T>especifica el GetEnumeratormétodo que se utiliza para iterar sobre secuencias.
Las interfaces se declaran igual que las clases:
tipo MyInterface = interfaz pública método MakeItSo : IEnumerable ; propiedad Bar : String lectura escritura ; fin ;Tenga en cuenta que, para las propiedades, los métodos getter y setter no se especifican explícitamente.
Delegados
Los delegados definen firmas para los métodos, de modo que estos puedan recibir parámetros (por ejemplo, funciones de devolución de llamada) o almacenarse en variables, etc. Son el equivalente en .NET, con seguridad de tipos, a los punteros a funciones. También se utilizan en eventos. Al asignar un método a un delegado, es necesario usar el @operador `asignar`, para que el compilador sepa que no se desea llamar al método, sino simplemente asignarlo.
Oxygene puede crear delegados anónimos; por ejemplo, se pueden pasar métodos al Invokemétodo de un control sin declarar el delegado:
método MainForm.MainForm_Load ( sender : System.Object ; e : System.EventArgs ) ; begin Invoke ( @DoSomething ) ; end ;DoSomethingEl compilador creará un delegado anónimo con la firma del método .
Oxygene admite delegados polimórficos, lo que significa que los delegados que tienen parámetros de tipos descendentes son compatibles con la asignación. Supongamos dos clases MyClassy MyClassEx = class(MyClass), entonces en el siguiente código BlubbExes compatible con la asignación a Blubb.
tipo delegate Blubb ( remitente : Object ; m : MyClass ) ; delegate BlubbEx ( remitente : Object ; mx : MyClassEx ) ;Los campos se pueden usar para delegar la implementación de una interfaz, si el tipo al que pertenecen implementa dicha interfaz:
Implementador = clase pública ( IMyInterface ) // ... implementar interfaz ... fin ;MyClass = public class ( IMyInterface ) fSomeImplementor : Implementor ; public implements IMyInterface ; //se encarga de implementar la interfaz end ;En este ejemplo, el compilador creará métodos y propiedades públicas en MyClass, que llaman a los métodos/propiedades de fSomeImplementor, para implementar los miembros de IMyInterface. Esto se puede usar para proporcionar una funcionalidad similar a la de un mixin. [ 6 ]
Métodos anónimos
Los métodos anónimos se implementan dentro de otros métodos. No son accesibles fuera del método a menos que se almacenen en un campo delegado. Los métodos anónimos pueden usar las variables locales del método en el que se implementan y los campos de la clase a la que pertenecen.
Los métodos anónimos son especialmente útiles cuando se trabaja con código que se supone que se ejecuta en un hilo de GUI, lo cual se hace en .NET pasando un método al Invokemétodo ( Control.Invokeen WinForms, Dispatcher.Invokeen WPF):
método Window1.PredictNearFuture ; // declarado como asíncrono en la interfaz begin // ... Calcular el resultado aquí , almacenar en la variable "theFuture " Dispatcher.Invoke ( DispatcherPriority.ApplicationIdle , method ; begin theFutureTextBox.Text : = theFuture ; end ) ; end ;Los métodos anónimos también pueden tener parámetros:
método Window1.PredictNearFuture ; // declarado como asíncrono en la interfaz begin // ... Calcular el resultado aquí, almacenar en la variable " theFuture " Dispatcher.Invoke ( DispatcherPriority.ApplicationIdle , method ( aFuture : String ) ; begin theFutureTextBox.Text : = aFuture ; end , theFuture ) ; end ;Ambos códigos fuente utilizan delegados anónimos .
Notificación de propiedad
La notificación de propiedades se utiliza principalmente para el enlace de datos , cuando la interfaz gráfica de usuario (GUI) necesita saber cuándo cambia el valor de una propiedad. El framework .NET proporciona las interfaces INotifyPropertyChangedy INotifyPropertyChanging(en .NET 3.5) para este propósito. Estas interfaces definen eventos que deben activarse cuando una propiedad cambia o ha cambiado.
Oxygene proporciona un notifymodificador que se puede usar en las propiedades. Si se usa este modificador, el compilador agregará las interfaces a la clase, las implementará y creará código para generar los eventos cuando la propiedad cambie o haya cambiado.
propiedad Foo : String leer fFoo escribir SetFoo ; notificar ; propiedad Bar : String ; notificar 'Blubb' ; //notificará que la propiedad "Blubb" fue modificada en lugar de "Bar"El modificador se puede usar en propiedades que tengan un método setter. El código para generar los eventos se agregará a este método durante la compilación.
Ejemplos de código
Hola Mundo
espacio de nombres HelloWorld ; interfaztipo HelloClass = clase pública método de clase Main ; fin ;implementaciónmétodo de clase HelloClass.Main ; begin writeLn ( ' ¡ Hola Mundo!' ) ; end ;fin .Contenedor genérico
espacio de nombres GenericContainer ; interfaztipo TestApp = clase pública método de clase Main ; fin ;Persona = clase propiedad pública Nombre : Cadena ; propiedad Apellido : Cadena ; fin ;implementaciónutiliza System.Collections.Generic ;método de clase TestApp.Main ; begin var myList := new List <Person> ; // inferencia de tipo myList.Add ( new Person ( FirstName := ' John' , LastName : = ' Doe' ) ) ; myList.Add ( new Person ( FirstName := 'Jane' , LastName := ' Doe' ) ) ; myList.Add ( new Person ( FirstName := ' James' , LastName : = ' Doe' ) ) ; Console.WriteLine ( myList [ 1 ] .FirstName ) ; // No se necesita conversión Console.ReadLine ; end ;fin .Método genérico
espacio de nombres GenericMethodTest ; interfaztype GenericMethodTest = static class public class method Main ; private class method Swap < T > ( var left , right : T ) ; class method DoSwap < T > ( left , right : T ) ; end ;implementaciónclass method GenericMethodTest . DoSwap < T > ( left , right : T ) ; begin var a := left ; var b := right ; Console . WriteLine ( 'Type: {0}' , typeof ( T )) ; Console . WriteLine ( '-> a = {0}, b = {1}' , a , b ) ; Swap < T > ( var a , var b ) ; Console . WriteLine ( '-> a = {0}, b = {1}' , a , b ) ; end ;método de clase GenericMethodTest . Main ; begin var a := 23 ; // inferencia de tipo var b := 15 ; DoSwap < Integer > ( a , b ) ; // no hay conversión descendente a Object en este método.var aa := 'abc' ; // inferencia de tipo var bb := 'def' ; DoSwap < String > ( aa , bb ) ; // no hay conversión descendente a Object en este método.DoSwap ( 1.1 , 1.2 ) ; // inferencia de tipo para parámetros genéricos Console . ReadLine () ; end ;método de clase GenericMethodTest . Swap < T > ( var left , right : T ) ; begin var temp := left ; left := right ; right := temp ; end ;fin .Salida del programa:
Tipo: System.Int32 -> a = 23, b = 15 -> a = 15, b = 23 Tipo: System.String -> a = abc, b = def -> a = def, b = abc Tipo: System.Double -> a = 1,1, b = 1,2 -> a = 1,2, b = 1,1
Diferencias entre Delphi y Oxygene
unit: Reemplazado con la palabra clave namespace . Dado que Oxygene no compila por archivo sino por proyecto, no depende del nombre del archivo. En su lugar, se utiliza la palabra clave unit o namespace para indicar el espacio de nombres predeterminado en el que se definen todos los tipos para ese archivo.procedureyfunction:methodes la palabra clave preferida, aunqueprocedureyfunctiontambién funcionan.overload: En Oxygene todos los métodos están sobrecargados por defecto, por lo que no se necesita ninguna palabra clave especial para esto..Create()Esta llamada al constructor ha sido reemplazada por lanewpalabra clave. Aún se puede habilitar porproject optionsmotivos de compatibilidad con versiones anteriores.stringLos caracteres en las cadenas están indexados desde cero y son de solo lectura. Las cadenas pueden contener valores nulos, por lo que comprobar si una cadena está vacía no siempre es suficiente.
Crítica
Algunas personas quisieran portar su código Delphi de Win32 a Oxygene sin realizar cambios importantes. Esto no es posible porque, si bien Oxygene se parece a Delphi, existen suficientes diferencias como para que sea incompatible con una simple recompilación. Aunque el nombre le da la apariencia de otra versión de Delphi, esto no es del todo cierto. [ 7 ]
Además de la diferencia de idioma, el marco de la Biblioteca de Componentes Visuales no está disponible en Oxygene. [ 8 ] Esto hace que la portabilidad sea aún más difícil porque el código clásico de Delphi depende en gran medida de la VCL.
Véase también
Referencias
- ↑ "Evolución del lenguaje Oxygene: Oxygene: Elementos" . Archivado del original el 5 de enero de 2018. Consultado el 4 de enero de 2018 .
- ↑ "Página de Embarcadero Prism, en la parte inferior de la página una imagen que indica que funciona con RemObjects Oxygene" . Archivado del original el 27/12/2011 . Recuperado el 14/12/2011 .
- ↑ "Prism XE4, ¿Dónde estás? | Blogs de RemObjects" . Archivado del original el 20 de junio de 2013. Consultado el 6 de junio de 2013 .
- ↑ "Sobrecarga de operadores - Delphi Prism" . Archivado del original el 8 de julio de 2011. Consultado el 9 de enero de 2010 .
- ↑ "Tipos integrados - Delphi Prism" . Archivado del original el 8 de julio de 2011. Consultado el 10 de enero de 2010 .
- ↑ "Proporcionar funcionalidad tipo Mixin - Delphi Prism" . Archivado del original el 8 de julio de 2011. Consultado el 17 de enero de 2010 .
- ↑ "Una discusión en Stack Overflow donde la gente comenta que Oxygene no es Delphi Win32" . Archivado del original el 25/10/2012 . Consultado el 25/07/2016 .
- ↑ "Reseña de Delphi Prism 2010 donde afirman en el tercer párrafo que VCL.net no está disponible" . Archivado del original el 4 de septiembre de 2009. Consultado el 14 de diciembre de 2009 .
Enlaces externos
- Sitio web oficial
- Lenguajes de programación .NET
- Lenguajes de programación basados en clases
- Mono (software)
- Lenguajes de programación orientados a objetos
- Compiladores de Pascal (lenguaje de programación)
- Familia de lenguajes de programación Pascal