Oxygene (anteriormente conocido como Chrome ) es un lenguaje de programación desarrollado por RemObjects Software para Common Language Infrastructure de Microsoft , Java Platform y Cocoa . Oxygene basado en Delphi 's Object Pascal , pero también tiene influencias de C # , Eiffel , Java , C # y otros lenguajes.
Desarrollador | Software RemObjects |
---|---|
Apareció por primera vez | 2005 [1] |
Plataforma | Infraestructura de lenguaje común , Java , Cocoa , CPU nativa, Windows 32/64 bit, Linux 32/64 bit, WebAssembly |
Licencia | Software de prueba |
Sitio web | elementscompiler |
Influenciado por | |
Delphi 's Object Pascal , C # |
En comparación con el ahora obsoleto Delphi.NET , Oxygene no enfatiza la compatibilidad total con versiones anteriores, sino que está diseñado para ser una "reinvención" del lenguaje, ser un buen ciudadano de las plataformas de desarrollo administradas y aprovechar todas las características y tecnologías proporcionadas por el Tiempos de ejecución de .NET y Java.
Oxygene es un producto comercial y ofertas plena integración en Microsoft 's Visual Studio IDE en Windows, así como su propia IDE llamado fuego para su uso en macOS . El compilador de la línea de comandos está disponible de forma gratuita. Oxygene es uno de los seis lenguajes compatibles con la cadena de herramientas subyacente de Elements Compiler, junto a C # , Swift , Java , Go y Mercury (basado en Visaul Basic.NET ).
De 2008 a 2012, RemObjects Software otorgó la licencia de su compilador y tecnología IDE a Embarcadero para ser utilizados 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 tiempos de ejecución de Java y Android. A partir del lanzamiento de XE4, Embarcadero Prism ya no forma parte del 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 Delphi en particular, pero fue diseñado para reflejar las pautas de la programación .NET y para crear ensamblados totalmente compatibles con CLR. Por lo tanto, se han eliminado o revisado algunas características secundarias del lenguaje conocidas de Object Pascal / Delphi, mientras que se han agregado al idioma una gran cantidad de características nuevas y más modernas, como Genéricos o Secuencias y consultas.
Oxygene es un lenguaje orientado a objetos, lo que significa que usa clases, que pueden contener datos y ejecutar código, para diseñar programas. [ aclaración necesaria ] Las clases son "prototipos" de objetos, como la idea de una manzana es el prototipo de la manzana que se puede comprar en una tienda. Se sabe que una manzana tiene un color y que se puede pelar: esos son los datos y el "código" ejecutable de la clase manzana.
Oxygene proporciona 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 una computadora para mejorar el rendimiento. Para alcanzar este objetivo, las tareas deben distribuirse entre varios subprocesos. El .NET Framework 's ThreadPool
de clase ofreció una manera de trabajar de manera eficiente con varios hilos. La Task Parallel Library (TPL) se introdujo en .NET 4.0 para proporcionar más funciones para la programación paralela.
Los operadores se pueden sobrecargar en Oxygene usando la class operator
sintaxis:
operador de clase implícito ( i : Integer ) : MyClass ;
Tenga en cuenta que para la sobrecarga de operadores, cada operador tiene un nombre, que debe usarse en la sintaxis de sobrecarga de operadores, porque, por ejemplo, "+" no sería un nombre de método válido en Oxygene. [4]
Estructura del programa
Oxygene no usa "Unidades" como lo hace Delphi, pero usa espacios de nombres .NET para organizar y agrupar tipos. Un espacio de nombres puede abarcar varios archivos (y ensamblajes), pero un archivo solo puede contener tipos de un espacio de nombres. Este espacio de nombres se define en la parte superior del archivo:
espacio de nombres ConsoleApplication1;
Los archivos de Oxygene se separan en una 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 uses
cláusula, que en Oxygene importa tipos de otros espacios de nombres:
usa System . Linq ;
Los espacios de nombres importados deben estar en el propio proyecto o en ensamblados referenciados. A diferencia de C #, en Oxygene, los nombres de alias no se pueden definir para espacios de nombres, solo para nombres de un solo tipo (ver más abajo).
Siguiendo la uses
cláusula, un archivo contiene declaraciones de tipo, como se las conoce en Delphi:
interfaztipo ConsoleApp = clase método de clase pública Main ; terminar ;
Como en C #, el método Main es el punto de entrada para cada programa. Puede tener un parámetro args : Array of String
para pasar argumentos de línea de comando al programa.
Se pueden declarar más tipos sin repetir la type
palabra clave.
La implementación de los métodos declarados se coloca en la sección de implementación:
implementación método de clase ConsoleApp . Principal ; begin // agrega tu propio código aquí Console . WriteLine ( 'Hola mundo.' ) ; terminar ;fin .
Los archivos siempre terminan con end.
Tipos
Como lenguaje .NET, Oxygene usa el sistema de tipos .NET: hay tipos de valor (como estructuras) y tipos de referencia (como matrices o clases).
Aunque no introduce tipos propios "predefinidos", Oxygene ofrece nombres genéricos más "pascalish" para algunos de ellos, [5] de modo que, por ejemplo, System.Int32
se pueden usar como Integer
y Boolean
( System.Boolean
), Char
( System.Char
), Real
( System.Double
) se unen a la familia de nombres de tipo pascal, también. El carácter de estructura de estos tipos, que forma parte de .NET, se conserva por completo.
Como en todos los lenguajes .NET, los tipos de Oxygene tienen visibilidad. En Oxygene, la visibilidad predeterminada es assembly
, que es equivalente a la internal
visibilidad en C #. El otro tipo de visibilidad posible es public
.
escriba MyClass = final de la clase pública ;
La visibilidad se puede configurar para cada tipo definido (clases, interfaces, registros, ...).
Se puede definir un nombre de alias para los tipos, que se pueden usar localmente o en otros ensamblados de Oxygene.
escriba IntList = public List < Integer >; // visible en otros ensamblajes de Oxygene SecretEnumerable = IEnumerable < String >; // no visible en otros ensamblajes
Los alias de tipo público no serán visibles para otros idiomas.
Registros
Los registros son lo que se denominan estructuras .NET en Oxygene. Se declaran como clases, pero con la record
palabra clave:
escriba MyRecord = método de registro Foo ; terminar ;
Como son solo 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 muy importante en el mundo .NET, el marco en sí hace un uso intensivo de ellas. Las interfaces son la especificación de un pequeño conjunto de métodos, propiedades y eventos que una clase debe implementar al implementar la interfaz. Por ejemplo, la interfaz IEnumerable
especifica el GetEnumerator
método que se utiliza para iterar sobre secuencias.
Las interfaces se declaran como clases:
escriba MyInterface = método de interfaz pública MakeItSo : IEnumerable ; barra de propiedades : cadena de lectura y escritura ; terminar ;
Tenga en cuenta que para las propiedades, el captador y el definidor no se especifican explícitamente.
Delegados
Los delegados definen firmas para los métodos, de modo que estos métodos puedan pasarse en parámetros (por ejemplo, devoluciones de llamada) o almacenarse en variables, etc. Son el equivalente NET seguro de tipos de punteros de función. También se utilizan en eventos. Al asignar un método a un delegado, uno tiene que usar el @
operador, para que el compilador sepa, que uno no quiere llamar al método sino simplemente asignarlo.
Oxygene puede crear delegados anónimos; por ejemplo, los métodos se pueden pasar al Invoke
método de un control sin declarar el delegado:
método MainForm . MainForm_Load ( remitente : System . Object ; e : System . EventArgs ) ; comenzar Invocar ( @ DoSomething ) ; terminar ;
El DoSomething
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. Suponga dos clases MyClass
y MyClassEx = class(MyClass)
, en el siguiente código, la BlubbEx
asignación es compatible con Blubb
.
escriba delegado Blubb ( remitente : Object ; m : MyClass ) ; delegar BlubbEx ( remitente : Objeto ; mx : MyClassEx ) ;
Los campos se pueden usar para delegar la implementación de una interfaz, si el tipo del que son implementa esta interfaz:
Implementador = clase pública ( IMyInterface ) // ... implementa la interfaz ... end ; MyClass = clase pública ( IMyInterface ) fSomeImplementor : Implementor ; público implementa IMyInterface ; // se encarga de implementar el final de la interfaz ;
En este ejemplo, el compilador creará propiedades y métodos públicos en MyClass
, que llaman a los métodos / propiedades de fSomeImplementor
, para implementar los miembros de IMyInterface. Esto se puede utilizar para proporcionar una funcionalidad similar a la de 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 estén almacenados dentro de un campo delegado. Los métodos anónimos pueden usar las variables locales del método en el que están implementados 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 debe ejecutarse en un hilo de GUI, que se hace en .NET pasando un método para hacer el Invoke
método ( Control.Invoke
en WinForms, Dispatcher.Invoke
en WPF):
método Window1 . PredictNearFuture ; // declarado como asíncrono en la interfaz begin // ... Calcule el resultado aquí, almacénelo en la variable "theFuture" Dispatcher . Invoke ( DispatcherPriority . ApplicationIdle , método ; comenzar theFutureTextBox . Text : = theFuture ; end ) ; terminar ;
Los métodos anónimos también pueden tener parámetros:
método Window1 . PredictNearFuture ; // declarado como asíncrono en la interfaz begin // ... Calcule el resultado aquí, almacénelo en la variable "theFuture" Dispatcher . Invoke ( DispatcherPriority . ApplicationIdle , método ( aFuture : String ) ; comienza elFutureTextBox . Text : = aFuture ; end , theFuture ) ; terminar ;
Ambos códigos fuente utilizan delegados anónimos .
Notificación de propiedad
La notificación de propiedad se utiliza principalmente para el enlace de datos, cuando la GUI tiene que saber cuándo cambia el valor de una propiedad. El marco .NET proporciona las interfaces INotifyPropertyChanged
y INotifyPropertyChanging
(en .NET 3.5) para este propósito. Estas interfaces definen eventos que deben activarse cuando se cambia o se cambia una propiedad.
Oxygene proporciona el notify
modificador, que se puede utilizar en 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 / fue cambiada.
propiedad Foo : String read fFoo write SetFoo ; notificar ; barra de propiedades : String ; notificar a 'Blubb' ; // notificará que se cambió la propiedad "Blubb" en lugar de "Bar"
El modificador se puede utilizar en propiedades que tienen un método de establecimiento. El código para generar los eventos se agregará a este método durante el tiempo de compilación.
Ejemplos de código
Hola Mundo
espacio de nombres HelloWorld ;interfaztipo HelloClass = clase método de clase pública Main ; terminar ; implementación método de clase HelloClass . Principal ; comenzar System . Consola . WriteLine ( '¡Hola mundo!' ) ; terminar ;fin .
Envase genérico
espacio de nombres GenericContainer ;interfaztipo TestApp = clase método de clase pública Main ; terminar ; Persona = clase propiedad pública Nombre : Cadena ; propiedad LastName : String ; terminar ; implementaciónusa System . Colecciones . Genérico ; método de clase TestApp . Principal ; begin var myList : = new List < Person >; // escribe inferencia myList . Agregar ( nueva Persona ( Nombre : = 'Juan' , Apellido : = 'Doe' )) ; myList . Agregar ( nueva Persona ( Nombre : = 'Jane' , Apellido : = 'Doe' )) ; myList . Agregar ( nueva Persona ( Nombre : = 'James' , Apellido : = 'Doe' )) ; Consola . WriteLine ( myList [ 1 ] . Nombre ) ; // No se necesita casting Console . ReadLine ; terminar ;fin .
Método genérico
namespace GenericMethodTest ;interfazescriba GenericMethodTest = estática clase pública clase de método principal ; método de clase privada Swap < T > ( var izquierda , derecha : T ) ; método de clase DoSwap < T > ( izquierda , derecha : T ) ; terminar ; implementación método de clase GenericMethodTest . DoSwap < T > ( izquierda , derecha : T ) ; begin var a : = left ; var b : = derecha ; Consola . WriteLine ( 'Tipo: {0}' , typeof ( T )) ; Consola . WriteLine ( '-> a = {0}, b = {1}' , a , b ) ; Intercambiar < T > ( var a , var b ) ; Consola . WriteLine ( '-> a = {0}, b = {1}' , a , b ) ; terminar ; método de clase GenericMethodTest . Principal ; comenzar var a : = 23 ; // tipo de inferencia var b : = 15 ; DoSwap < Entero > ( a , b ) ; // no rebajar a Object en este método. var aa : = 'abc' ; // tipo de inferencia var bb : = 'def' ; DoSwap < Cadena > ( aa , bb ) ; // no rebajar a Object en este método. DoSwap ( 1.1 , 1.2 ) ; // tipo de inferencia para parámetros genéricos Console . ReadLine () ; terminar ; método de clase GenericMethodTest . Intercambiar < T > ( var izquierda , derecha : T ) ; begin var temp : = left ; izquierda : = derecha ; derecha : = temp ; terminar ;fin .
Salida del programa:
Tipo: System.Int32-> a = 23, b = 15-> a = 15, b = 23Tipo: System.String-> a = abc, b = def-> a = def, b = abcTipo: Sistema Doble-> a = 1,1, b = 1,2-> a = 1,2, b = 1,1
Diferencias entre Delphi y Oxygene
- unidad : reemplazado por la palabra clave del espacio de nombres . Dado que Oxygene no compila por archivo sino por proyecto, no depende del nombre del archivo. En su lugar, la palabra clave unidad o espacio de nombres se utiliza para denotar el espacio de nombres predeterminado en el que se definen todos los tipos para ese archivo.
- procedimiento y función : método es la palabra clave preferida, aunque procedimiento y función aún funcionan.
- sobrecarga : en Oxygene todos los métodos están sobrecargados de forma predeterminada, por lo que no se necesita una palabra clave especial para esto
- .Create () : esta llamada al constructor ha sido reemplazada por la nueva palabra clave. Todavía se puede habilitar en las opciones del proyecto por razones heredadas
- cadena : los caracteres de las cadenas son de base cero y de solo lectura. Las cadenas pueden tener valores nulos, por lo que las pruebas con cadenas vacías no siempre son suficientes.
Crítica
A algunas personas les gustaría trasladar su código Win32 Delphi a Oxygene sin realizar cambios importantes. Esto no es posible porque, si bien Oxygene se parece a Delphi, hay suficientes cambios para que sea incompatible con una simple recompilación. Si bien el nombre le da la apariencia de otra versión de Delphi, eso 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 migración sea aún más difícil porque el código Delphi clásico depende en gran medida de la VCL.
Ver también
- C#
- Objeto Pascal
- Embarcadero Delphi
- Pascal libre
- Eiffel
- Java
Referencias
- ^ http://www.elementscompiler.com/elements/oxygene/history.aspx
- ^ "Página de Embarcadero Prism, en la parte inferior de la página una imagen que indica que es impulsada por RemObjects Oxygene" .
- ^ "Copia archivada" . Archivado desde el original el 20 de junio de 2013 . Consultado el 6 de junio de 2013 .Mantenimiento de CS1: copia archivada como título ( enlace )
- ^ "Copia archivada" . Archivado desde el original el 8 de julio de 2011 . Consultado el 9 de enero de 2010 .Mantenimiento de CS1: copia archivada como título ( enlace )
- ^ "Copia archivada" . Archivado desde el original el 8 de julio de 2011 . Consultado el 10 de enero de 2010 .Mantenimiento de CS1: copia archivada como título ( enlace )
- ^ "Copia archivada" . Archivado desde el original el 8 de julio de 2011 . Consultado el 17 de enero de 2010 .Mantenimiento de CS1: copia archivada como título ( enlace )
- ^ "Una discusión de Stack Overflow donde la gente comenta que Oxygene no es Delphi Win32" . Archivado desde el original el 25 de octubre de 2012 . Consultado el 25 de julio de 2016 .
- ^ "Revisión de Delphi Prism 2010 donde afirman en el tercer párrafo que VCL.net no está disponible" .
enlaces externos
- Página web oficial