Eiffel (lenguaje de programación)
Eiffel es un lenguaje de programación orientado a objetos que sigue el estándar ISO diseñado por Bertrand Meyer (defensor de los lenguajes orientados a objetos y autor de la construcción de Software Orientado a Objetos) y Software Eiffel. El diseño del lenguaje esta estrechamente relacionado con el método de programación Eiffel. Ambos se basan en una serie de principios incluyendo: el diseño por contrato, la separación de comandos y consultas, el principio de acceso uniforme, el principio de elección única, el principio abierto-cerrado y la separación operación-operando. Muchos conceptos inicialmente introducidos por Eiffel aparecen más tarde en Java, C# y otros lenguajes. Nuevas ideas de diseño de lenguaje, particularmente a través del proceso de estandarización ECMA/ISO, se continúan incorporando al lenguaje Eiffel. CaracterísticasLas características claves del lenguaje Eiffel incluyen:
Los objetivos de diseñoEiffel destaca enunciados declarativos sobre el código de procedimiento y los intentos de eliminar la necesidad de instrucciones de contabilidad. Eiffel evita trucos o técnicas de codificación destinadas como sugerencias de optimización para el compilador. El objetivo no es sólo para hacer el código más fácil de leer, sino también para permitir a los programadores concentrarse en los aspectos importantes de un programa sin atascarse en los detalles de implementación. La simplicidad de Eiffel está destinada a promover respuestas sencillas, extensibles, reutilizables y fiables a los problemas informáticos. Los compiladores de programas informáticos escritos en Eiffel ofrecen amplias técnicas de optimización, tales como autommatic in-lining, que alivian el programador de parte de la carga, mientras que la optimización de la producción de código cuya eficacia es comparable a la de código escrito en C++ [cita requerida]. AntecedentesEiffel fue desarrollado originalmente por Eiffel Software, una compañía fundada por Bertrand Meyer. El Software de Construcción Orientado a Objetos contiene un tratamiento detallado de los conceptos y la teoría de la tecnología de objetos que llevaron al diseño de Eiffel.[1] El objetivo de diseño detrás del lenguaje Eiffel, las librerías y los métodos de programación es permitir a los programadores crear módulos de software fiables y reutilizables. Eiffel soporta herencia múltiple, generalidad, polimorfismo, encapsulación, conversiones de tipo seguro, y covarianza de los parámetros. La contribución más importante de Eiffel de la ingeniería de software es el diseño por contrato (DBC), en el que se emplean las aserciones, precondiciones, postcondiciones y clases invariantes para ayudar a garantizar la corrección del programa sin sacrificar la eficiencia. El diseño de Eiffel se basa en la teoría de la programación orientada a objetos, con solo un poco influencia de otros paradigmas o algunos conceptos por el soporte de código heredado. Eiffel soporta formalmente los tipos abstractos de datos. En el diseño de Eiffel, un texto de software debe ser capaz de reproducir su documentación de diseño del texto en si, usando una implementación formalizada del tipo de datos abstracto. El lenguaje interactivo de aprendizaje Blue, precursor de BlueJ, también está basado en Eiffel. El Apple Media Tool incluye un Apple Media Lenguaje basado en Eiffel. Implementaciones y entornosEiffelStudio es un entorno de desarrollo integrado disponible en virtud de un código abierto o licencia comercial. Ofrece un entorno orientado a objetos para la ingeniería del software. EiffelEnvision es un plugin para Microsoft Visual Studio que permite a los usuarios editar, compilar y depurar proyectos Eiffel desde el Microsoft Visual Studio IDE. EiffelStudio y EiffelEnvision son gratuitos para uso no comercial. Hay otras cuatro implementaciones de código abierto: "The Eiffel Compiler" tecomp, Gobo Eiffel, SmartEiffel - la implementación GNU, basada en una versión anterior del lenguaje-, LibertyEiffel-basado el compilador de SmartEiffel- y VisualEiffel. Diversos lenguajes de programación incorporan elementos aportados por primera vez en Eiffel. Sather, por ejemplo, se basó originalmente en Eiffel, pero ha variado desde entonces, y ahora incluye características de la programación funcional. Especificaciones y normasLa definición del lenguaje Eiffel es un estándar internacional de la ISO. El estándar fue desarrollado por Ecma International, que por primera vez aprobada la norma, el 21 de junio de 2005, como estándar ECMA 367, Eiffel: Analysis, Design and Implementation Language. En junio de 2006, ECMA e ISO aprobaron la segunda versión. En noviembre de 2006, la ISO publicó por primera vez. El estándar se puede encontrar y utilizar de una manera gratuita en la web de ECMA.[2] La versión de ISO[3] es idéntica en todos los aspectos salvo en el formato. Eiffel Software's, "tecomp: The Eiffel Compiler" i Eiffel-library-developer de Gobo se han comprometido a aplicar el estándar; Eiffel Software's EiffelStudio 6.1 and "tecomp: The Eiffel Compiler" implementan algunos de los principales nuevos mecanismos- en particular, los agentes en línea, asignadores de órdenes, notación parenterizada, herencia no conforme, y los tipos anexos. El equipo de SmartEiffel se ha apartado de este estándar para crear su propia versión del lenguaje, que creen que está más cerca del estilo original de Eiffel. Object Tools no ha revelado si en futuras versiones de su compilador de Eiffel cumplirá con el estándar. El estándar cita los siguientes predecesores de especificaciones del lenguaje Eiffel:
La versión actual del estándar de junio de 2006 contiene algunas inconsistencias (por ejemplo, las redefiniciones de la covarianza). El comité ECMA no ha anunciado ningún calendario ni en que dirección se resolverán estas inconsistencias. Sintaxis y la semánticaEstructura generalUn "sistema" o "programa" Eiffel es una colección de clases. Por encima del nivel de clases, Eiffel define el cluster, que es esencialmente un grupo de clases, y posiblemente de subclubsters. Las agrupaciones no son una estructura de control sintáctica, sino más bien una convención de la organización estándar. Normalmente una aplicación Eiffel se organizara con cada clase en un archivo separado, y cada clúster en un directorio o carpeta que contiene los ficheros de las clases. En esta organización, los subclústers son subdirectorios. Por ejemplo, en virtud de las convenciones estándar de la organización y el entorno, x.e podría ser el nombre de un fichero que define una clase llamada X. Una clase contiene características, que son similares a los "miembros, "atributos" o "métodos" en otros lenguajes de programación orientados a objetos. Una clase también define a sus invarianzas,y contiene otras propiedades, como una sección de "notas" para documentación y metadatos. Los tipos estándar de datos como entero, string o array, son todos ellos clases. Cada sistema tiene que tener una clase designada como raíz, y uno de sus procedimientos de creación designado como "procedimiento raíz". La ejecución de un sistema consiste en la creación de una instancia de la clase raíz y en ejecutar el procedimiento raíz. En general, eso crea nuevos objetos, llama a nuevas características, y así sucesivamente. Eiffel tiene cinco instrucciones básicas ejecutables: asignación, creación de objetos, llamada de rutina, condición, e iteración. Las estructuras de Eiffel de control son estrictas en el cumplimiento de la programación estructurada: cada bloque tiene exactamente una entrada y una salida. AlcanceA diferencia de muchos lenguajes orientados a objetos, pero como Smalltalk, Eiffel no permite una asignación en los campos de los objetos, excepto dentro de las características de un objeto. Eiffel hace hincapié en ocultar la información, y la abstracción de datos, en requerir interfaces formales para la mutación de datos. Para expresarlo en el formato de otros lenguajes orientado a objetos, todos los campos Eiffel son privados, y los métodos "set" son necesarios para modificar los valores. Una consecuencia de esto es que el método "set" puede, y normalmente lo hace, implementa las invariancias por los cuales Eiffel proporciona sintaxis. "Hola Mundo"El primer contacto con un lenguaje de programación se hace a menudo con el uso de un programa "Hola, mundo!". Este programa escrito en Eiffel podría ser: class
HOLA_MUNDO
create
hacer
feature
hacer
do
print ("Hola, mundo!%N")
end --hacer
end --HOLA_MUNDO
Este programa contiene la clase Diseño por contratoEl concepto de diseño por contrato es fundamental para Eiffel. Los mecanismos están estrechamente integrados con el lenguaje. Los contratos guían la redefinición de las características en la herencia.
Además, el lenguaje soporta una "instrucción de verificación" (una especie de "asserción") y los invariantes de bucle. Características, órdenes y consultasLa propiedad principal de una clase es que contiene un conjunto de características. Como una clase presenta un conjunto de objetos en tiempo de ejecución, o "casos", una característica es un atributo o una operación en estos objetos. Hay dos tipos de funciones: consultas y órdenes. Una consulta proporciona información sobre una instancia. Una orden modifica una instancia. La distinción consulta-orden es importante para el método Eiffel. En particular:
SobrecargaEiffel no permite la sobrecarga de argumentos. Cada nombre de característica dentro de una clase siempre se asigna a una característica específica dentro de la clase. Un nombre, dentro de una clase, significa una cosa. Esta opción de diseño ayuda a la legibilidad de las clases, evitando una de las causas de ambigüedad sobre que rutina será invocada con una llamada. También simplifica el mecanismo del lenguaje. En particular, eso es lo que hace posible el mecanismo de la herencia múltiple de Eiffel.[4] Los nombres pueden, por descontado, son reutilizadas en diferentes clases. Por ejemplo, el operador "+" se define en diversas clases: INTEGER, REAL, STRING, etc. GenericidadLas clases pueden ser genéricas, para expresar que están parametrizadas para tipos. Los parámetros genéricos aparecen entre corchetes: class LISTA [G] ...
item: G do ... end
pone (x: G) do ... end
La n := il.item
wl.pone (w)
También es posible tener "restricciones" de los parámetros formales, de manera que el parámetro real a de heredar de una clase dada, la "restricción". Por ejemplo, en class TABLA_HASH [G, CLAVE -> HASHABLE]
una derivación Fundamentos de la herenciaPara heredar de otra o otras, una clase incluirá una cláusula de heredar al principio: class C inherit
A
B
-- ... Resto de la declaración de la clase ...
La clase puede redefinir algunas o todas las características heredadas. Eso ha de ser declarado explícitamente al comienzo de la clase a través de la cláusula class C inherit
A
redefine f, g, h end
B
redefine u, v end
Clases y características diferidasLas clases se pueden definir con deferred class en lugar de con class para indicar que la clase no puede ser instanciada directamente. Las clases no instanciables se dicen clases abstractas en otros lenguajes de programación orientados a objetos. En el lenguaje Eiffel, solo se pueden crear instancias de una clase "efectiva" (que puede ser una descendiente de una clase diferida). Una característica también puede ser diferida mediante cláusula deferred en lugar de una cláusula do. Si una clase tiene características diferidas se ha de declarar como diferida, pero, no obstante una clase sin características diferidas puede ser diferida por sí misma. Las clases diferidas juegan un papel parecido al de las interfaces en lenguajes como Java, a pesar de que muchos teóricos de la programación orientada a objetos crean que las interfaces son en gran medida una respuesta a la falta de Java de herencia múltiple (que tiene Eiffel). Cambio de nombreUna clase que hereda de otra u otras obtiene todas sus características, por defecto con sus nombres originales. Puede cambiar el nombre a través de la cláusula rename. Eso es necesario en el caso de herencia múltiple si hay conflictos de nombres entre las características heredadas, sin cambiar el nombre, la clase resultante violaría el principio de no sobrecargar, antes mencionada, y por tanto, no sería válida. TuplesLos tipos tuples pueden ser vistos como una forma simple de clase, proporcionando solo los atributos y el correspondientemente método "set". Un tipo tupla típico TUPLE [nom: STRING; pes: REAL; data: DATE] podría ser utilizado para describir una simple acta de nacimiento si no fuese necesaria una clase. Un ejemplo de esta tupla es simplemente una secuencia de valores con el tipo dado, entre paréntesis, como ["Maria", 3.5, anit] Los componentes de una tupla como tal se pueden acceder si las etiquetas de la tupla son atributos de una clase, por ejemplo, si t ha sido asignado a la tupla entonces t.pes tiene un valor 3.5. Gracias a la noción de asignador de órdenes, la notación de puntos también se puede utilizar para asignar los componentes de esta tupla, como en t.pes := t.pes + 0.5 Las etiquetas tuple son opcionales, de manera que también es posible escribir un tipo tupla como TUPLE [STRING, REAL, DATE]. (En algunos compiladores esta es la única forma de tuple, ya que las etiquetas se van introduciendo en el estándar ECMA). La especificación precisa de, por ejemplo, TUPLE [A, B, C] que describe secuencias de al menos tres elementos, el primero de tres que son de los tipos A, B, C, respectivamente. Como resultado TUPLE [A, B, C] se ajusta a (se puede asignar a) TUPLE [A, B], a TUPLE [A] y TUPLE (sin parámetros), la tuple más grande se ajusta a todas las otras tuples. AgentesEl mecanismo del' "agente" de Eiffel agrupa les operaciones dentro de los objetos. Este mecanismo puede ser utilizado por la interacción, la programación dirigida por eventos, y en otros contextos es útil para pasar operaciones alrededor de la estructura del programa. Otros lenguajes de programación, especialmente los que hacen énfasis en la programación funcional, permiten un patrón similar con las continuaciones, clausuras, o generadores; los agentes Eiffel enfatizan el paradigma de los lenguajes orientados a objetos, y usa una sintaxis y semántica similares a los bloques de código en Smalltalk y Ruby. Por ejemplo, para ejecutar el bloque accion_propia para cada elemento de lista_propia, se podría escribir: lista_propia.do_all (agent accion_propia) Para ejecutar accion_propia solo los elementos que satisfacen condicion_propia, una limitación de filtro se puede añadir: lista_propia.do_ifsi (agent accion_propia, agente condicion_propia) En estos ejemplos, accion_propia y condicion_propia son rutinas. Prefijándolos con agente cede un objeto que representa la rutina correspondiente, con todas sus propiedades, en particular, la capacidad de ser llamado con los argumentos adecuados. Así que si a representa un objeto (por ejemplo, porque a es el argumento para do_all), la instrucción a.call ([x]) llamara a la rutina original con el argumento x, como si hubiesen llamado directamente a la rutina original: accion_propia (x). Los argumentps para llamar se pasan como una tupla, aquí [x]. Es posible mantener algunos argumentos para un agente abierto y hacer los otros cerrados. Los argumentos abiertos se pasan como argumentos para la llamada (call): que se proporcionan en el momento de utilizar el agente. Los argumentos son siempre cerrados en el momento de la definición del agente. Por ejemplo, si acción2 tiene dos argumentos, la iteración lista_propia.do_all (agent acción2 (?, y)) itera acción2 (x, y) para valores sucesivos de x, donde el segundo argumento ha quedado establecido en y. El signo de interrogación? indica un argument abierto, y es un argumento cerrado del agente. Hay que tener en cuenta que la sintaxis básica agent f es una abreviatura de agent f (?,?,...) con todos los argumentos abiertos. También es posible crear el target de un agente libre a través de la notación {T}? donde T es el tipo del objetivo. La distinción entre operandos abiertos y cerrados (operandos = argumentos + target) corresponde a la distinción entre las variables libres i ligades en el cálculo lambda. Un agente de expressión, como acción2 (?, y) con algunos operandos cerrados y algunos abiertos corresponde a una versión de la operación original currificada sobre los operandos cerrados. El mecanismo de agent ha estado recientemente generalizado por permetro la definición de un agent sin hacer referencia a una rutina existente (como accion_propia, condicion_propia, acción2), a través de agentes en línea como en lista_propia.do_all (agent (s: STRING) require no_void: s /= Void do s.append_character (',') ensure appended: s.count = old s.count + 1 end) El agente en línea se ha pasado aquí puede tener todos la elementos de una rutina normal, incluyendo precondición, postcondición, la cláusula de rescate (aquí no se usa), y una signatura completa. Esto evita la definición de rutinas cuando todo lo que se necesita es un cálculo que se agrupara en un agent. Esto es útil en particular para los contratos, como en una cláusula invariante que expresa que todos los elementos de una lista son positivos: lista_propia.for_all (agent (x: INTEGER): BOOLEAN do Result := (x > 0) end) El mecanismo agent actual deja una posibilidad de error en tiempos de ejecución (en caso de una rutina con n argumentos se pase a un agent que está esperando m arguments siendo m < n). Esto puede evitarse mediante un control en tiempo de ejecución a través de la precondición valid_arguments de la llamada (call). Hay diversas propuestas para una corrección puramente estática de este problema, incluyendo una propuesta de camabio en el lenguaje de Ribet y otros.[5] Rutinas de ejecución únicaEl resultado de una rutina puede ser almacenado en memoria caché y la palabra clave objecte_compartido: ALGUN_TIPO
once
create Result.fer (args)
-- Esto creara el objeto y volvera una referencia a la misma a través de 'Result'.
end --objeto_compartido
El objeto retornado - A menudo, las "rutinas de ejecución única", realizan una inicialización necesaria: múltiples llamadas a una library que pueden incluir una llamada al procedimiento de inicialización, pero solo la primera llamada se realizan las acciones requeridas. Usando este patrón la inicialización puede ser descentralizada, evitando la necesidad de un módulo especial de inicialización. Las "rutinas de ejecución única" son similares en propósito y efecto al patrón Singleton de muchos lenguajes de programación, y para el patrón utilizado por Borg en Python. Por defecto, una "rutina de ejecución única" se llama una vez por hilo de ejecución. La semántica se puede ajustar a una vez por proceso o una vez por objeto calificando con una palabra clave "once", por ejemplo, ConversionesEiffel proporciona un mecanismo que permite las conversiones entre diferentes tipos. El mecanismo coexiste con el de herència y el de complementa. Para evitar cualquier confusión entre los dos mecanismos, el diseño ha de cumplir el siguiente principio:
Por ejemplo El mecanismo de conversión simplemente generaliza las normas ad hoc de conversión (tal y como entre enteros - my_string := my_data
como un acceso directo para el uso de la creación explícita de un objeto con un procedimiento de conversión: create my_string.make_from_date(my_data)
Para hacer la primera forma posible como un sinónimo de la segunda, hay bastante con incluir el procedimiento de creación (constructor) Como en otro ejemplo, si existe un procedimento de conversión incluye en Dia_de_la_Bastilla := [14, "Julio", 1789]
Tratamiento de excepcionesEl Manejo de excepciones en Eiffel es basa en los principios de diseño por contrato. Por ejemplo, se produce una excepción cuando quien llama a una rutina no satisface la precondición, o cuando en una rutina no se puede garantizar el cumplimiento de la postcondición. En Eiffel, el tratamiento de excepciones no se utiliza para a les estructuras de control o para corregir errores de los datos de entrada. Un controlador de excepciones Eiffel se define utilizando la palabra clave connect_to_server (server: SOCKET)
-- Connect to a server or give up after 10 attempts.
require
server /= Void and then server.address /= Void
local
attempts: INTEGER
do
server.connect
ensure
connected: server.is_connected
rescue
if attempts < 10 then
attempts := attempts + 1
retry
end
end
Esto ejemplo es, sin duda, imperfecto, pero en los programes más simples tendría que estar previsto que pueda fallar la conexión. Pero a la mayoría de los programes sería mejor un nombre de rutina como ConcurrenciaHay disponibles varias librerías de redes y de hilos de ejecución, como EiffelNet y EiffelThreads. Un modelo de concurrencia de Eiffel, basado en los conceptos de diseño por contrato, es el SCOOP, o Programación Concurrente Simple Orientada a Objetos, aún no forma parte de la definición oficial del lenguaje, pero está disponible como a un "add-on" de ETH Zurich. CAMEO[6] es una variación (no implementada) de SCOOP de Eiffel. La concurrencia también interactúa con las excepciones. Les excepciones asíncronas pueden ser un problema (una rutina activa una excepción después de que su llamada se termine).[7] Sintaxis de operadores y corchetes, las órdenes de asignaciónLa visión del cálculo en Eiffel es completamente orientada al objeto en el sentido que cada operación es relativa a un objeto, el'"objetivo". Así, por ejemplo, una suma [1] a + b
es conceptualmente entendida como si se tratase de una llamada a la función [2] a.mes (b)
con el objetivo Por descontado, [1] es la sintaxis convencional y la preferida normalmente. La sintaxis del operador hace posible el uso de una o de la otra manera, al declarar la función (por ejemplo, en mes alias "+" (un_altre: INTEGER): INTEGER
-- ... Declaración normal de la función...
end
La gamma de operadores que pueden utilizarse como un "alias" es bastante amplio, e incluyen operadores predefinidos como "+" pero también "los operadores libres" hechos de símbolos no alfanuméricos. Eso hace posible diseñar notaciones especiales infijos y prefijos, por ejemplo, en aplicaciones de matemáticas y de física. Cada clase podrá tener una función alias de "[]", el operador "corchete", permito que la notación numero := Libreta_de_telefonos ["JULI FERRER"]
Las "órdenes de asignación" son un mecanismo de acompañamiento diseñado con el mismo espíritu de permitir la solidez, la conveniente notación reinterpretada en el marco de la programación orientada a objetos. Las órdenes de asignación permiten sintaxis de asignación como llamadas a procedimentos "setter". Una asignación adecuada no puede ser de la forma item alias "[]" (clave: STRING): ELEMENT [3]
-- El elemento de de la clave 'clave'.
-- (interrogación del "Getter")
do
...
end
put (e: ELEMENT; clau: STRING)
-- Insertar el elemento 'e', asociándolo con la clave 'clave'.
-- (ordre "Setter")
do
...
end --
Después, para insertar un elemento que debe utilizar una llamada explícita a la orden setter: [4] Libreta_de_telefonos.put (Nueva_persona, "JULI FERRER")
Es posible escribir este equivalente como [5] Libreta_de_telefonos ["JULI FERRER"] := Nueva_persona
(De la misma manera que item alias "[]" (key: STRING): ELEMENT assign put
Eso declara Nota: La lista de argumentos de la asignación de Propiedades léxicas y sintácticasEiffel no distingue entre mayúsculas y minúsculas. Eso quiere decir que Los comentarios son introducidos por -- (dos guiones consecutivos) y se extienden hasta el final de línea. El punto y coma (;), como separador de instruccions, es opcional. La mayoría de las veces el punto y coma es omitido, excepto para separar múltiples instrucciones en una línea. Eso se traduce en menos desorden en la página del programa. No hay anidación de las declaraciones de las características y de la clase. Como resultado la estructura de una clase Eiffel es simple: algunas cláusulas a nivel de clase (herencia, invariante) y una sucesión de declaraciones de características, están todas al mismo nivel. Se acostumbra a agrupar las características en diferentes "cláusulas de características" para facilitar más la lectura, con un conjunto estándar de etiquetas de característica básica que figuren en un orden estándar, por ejemplo: class TABLA_HASH [ELEMENT, KEY -> HASHABLE] inherit TABLE [ELEMENT]
feature -- Inicialización
-- ... Declaración de las órdenes de inicialización (procedimientos de creación/constructores) ...
feature -- Acceso
-- ... Declaraciones de las consultes no booleanas sobre el estado del objeto, per ejemplo, item ...
feature -- Informe de situación
-- ... Declaraciones de consultes booleanas sobre el estado del objeto, por ejemplo, is_empty...
feature -- el cambio del elemento
-- ... Declaraciones de órdenes que cambian la estructura, por ejemplo, put ...
-- etc.
end -- TABLA_HASH
En contraste con los lenguajes de programación funcionales más complicados, Eiffel hace una clara distinción entre las expresiones y las instrucciones. Eso esta en consonancia con el principio de separación orden-consulta del método Eiffel. Convenciones de estiloGran parte de la documentación de Eiffel utiliza las convenciones de estilo distintivas, diseñadas para velar por un aspecto consistente. Algunas de estas convenciones se aplican al formato de código en si, y otros para la representación tipográfica estándar del código Eiffel en formatos y publicaciones en las que estas convenciones son posibles. Mientras que el lenguaje no distingue entre mayúsculas y minúsculas, las normas de estilo de prescriben que los nombres de clase estén totalmente en mayúsculas ( La especificación de Eiffel incluye directrices para los textos del programa que muestra en formato composición tipográfica: palabras clave en class HOLA_MUNDO create make feature make do print ("Hola, mundo!") end --make end --HOLA_MUNDO Interfaces para otras herramientas y lenguajesEiffel es un lenguaje puramente orientado a objetos, pero proporciona una arquitectura abierta para la interconexión con otro programa "externo" en cualquier lenguaje de programación. Es posible, por ejemplo, programar a nivel máquina y sistema operativo en C. Eiffel proporciona una interfaz sencilla para las rutinas en C, incluido el soporte a "C en línea" (escribir el cuerpo de una rutina de Eiffel en C, en general para pequeñas operaciones a nivel máquina). Aunque no exista una conexión directa entre Eiffel y C, muchos compiladores son Eiffel (Visual Eiffel no es una excepción) el Código fuente surgido de C como un lenguaje intermedio, a someter a un compilador de C, para la optimización y la portabilidad. El compilador Eiffel de tecomp puede ejecutar cogido Eiffel directamente (como un intérprete) sin tener que pasar a través de un código C intermedio ni emitir código C que se pasara a un compilador de C para obtener el código nativo optimizado. En.NET, el compilador EiffelStudio genera directamente código en CIL (Common Intermediate Language). El compilador SmartEiffel puede también generar la salida en bytecode de Java. Notas y referencias
Enlaces externos
|