En informática , una especificación de lenguaje de programación (o estándar o definición ) es un artefacto de documentación que define un lenguaje de programación para que los usuarios y los implementadores puedan ponerse de acuerdo sobre lo que significan los programas en ese lenguaje. Las especificaciones suelen ser detalladas y formales, y las utilizan principalmente los implementadores, y los usuarios se refieren a ellas en caso de ambigüedad; los usuarios citan con frecuencia la especificación C ++, por ejemplo, debido a su complejidad. La documentación relacionada incluye una referencia del lenguaje de programación , que está destinada expresamente a los usuarios, y una justificación del lenguaje de programación., que explica por qué la especificación está escrita como está; estos suelen ser más informales que una especificación.
Estandarización
No todos los lenguajes de programación principales tienen especificaciones, y los lenguajes pueden existir y ser populares durante décadas sin una especificación. Un lenguaje puede tener una o más implementaciones, cuyo comportamiento actúa como un estándar de facto , sin que este comportamiento esté documentado en una especificación. Perl (a través de Perl 5 ) es un ejemplo notable de un lenguaje sin una especificación, mientras que PHP solo se especificó en 2014, después de estar en uso durante 20 años. [1] Un lenguaje puede implementarse y luego especificarse, o especificarse y luego implementarse, o pueden desarrollarse juntos, lo que es una práctica habitual en la actualidad. Esto se debe a que las implementaciones y especificaciones se verifican entre sí: escribir una especificación requiere establecer con precisión el comportamiento de una implementación, y la implementación verifica que una especificación sea posible, práctica y consistente. Escribir una especificación antes de una implementación se ha evitado en gran medida desde ALGOL 68 (1968), debido a dificultades inesperadas en la implementación cuando se aplaza la implementación. Sin embargo, los lenguajes todavía se implementan ocasionalmente y ganan popularidad sin una especificación formal: una implementación es esencial para su uso, mientras que una especificación es deseable pero no esencial (informalmente, "conversaciones de código").
ALGOL 68 fue el primer lenguaje importante (y posiblemente uno de los últimos) para el que se realizó una definición formal completa antes de su implementación.
- CHA Koster , [2]
Formularios
Una especificación de lenguaje de programación puede tomar varias formas, incluidas las siguientes:
- Una definición explícita de la sintaxis y semántica del lenguaje. Si bien la sintaxis se especifica comúnmente usando una gramática formal, las definiciones semánticas pueden escribirse en lenguaje natural (por ejemplo, el enfoque adoptado para el lenguaje C ) o en una semántica formal (por ejemplo, las especificaciones estándar ML [3] y Scheme [4] ). . Un ejemplo notable es el lenguaje C, que ganó popularidad sin una especificación formal, sino que se describió como parte de un libro, The C Programming Language (1978), y solo mucho más tarde se estandarizó formalmente en ANSI C (1989).
- Una descripción del comportamiento de un compilador (a veces llamado "traductor") para el lenguaje (por ejemplo, el lenguaje C ++ y Fortran ). La sintaxis y semántica del lenguaje debe inferirse de esta descripción, que puede estar escrita en lenguaje natural o formal.
- Una implementación de modelo , a veces escrita en el lenguaje que se especifica (por ejemplo, Prolog ). La sintaxis y la semántica del lenguaje son explícitas en el comportamiento de la implementación del modelo.
Sintaxis
La sintaxis de un lenguaje de programación generalmente se describe mediante una combinación de los dos componentes siguientes:
- una expresión regular que describe sus lexemas , y
- una gramática libre de contexto que describe cómo se pueden combinar los lexemas para formar un programa sintácticamente correcto.
Semántica
Formular una semántica rigurosa de un lenguaje de programación grande, complejo y práctico es una tarea abrumadora incluso para especialistas experimentados, y la especificación resultante puede ser difícil de entender para cualquiera que no sea un experto. Las siguientes son algunas de las formas en que se puede describir la semántica del lenguaje de programación; todos los idiomas utilizan al menos uno de estos métodos de descripción, y algunos idiomas combinan más de uno [5]
- Lenguaje natural : descripción por lenguaje natural humano.
- Semántica formal : Descripción por matemáticas .
- Implementaciones de referencia : Descripción por programa informático
- Conjuntos de pruebas : descripción mediante ejemplos de programas y sus comportamientos esperados. Si bien pocas especificaciones de lenguaje comienzan de esta forma, la evolución de algunas especificaciones de lenguaje se ha visto influenciada por la semántica de un conjunto de pruebas (por ejemplo, en el pasado, la especificación de Ada se ha modificado para que coincida con el comportamiento del conjunto de pruebas de evaluación de la conformidad de Ada ) .
Lenguaje natural
Los lenguajes más utilizados se especifican utilizando descripciones de lenguaje natural de su semántica. Esta descripción suele adoptar la forma de un manual de referencia para el idioma. Estos manuales pueden ocupar cientos de páginas, por ejemplo, la versión impresa de The Java Language Specification, 3.ª edición. tiene 596 páginas.
La imprecisión del lenguaje natural como vehículo para describir la semántica del lenguaje de programación puede generar problemas con la interpretación de la especificación. Por ejemplo, la semántica de los subprocesos de Java se especificó en inglés y más tarde se descubrió que la especificación no proporcionaba una guía adecuada para los implementadores. [6]
Semántica formal
La semántica formal se basa en las matemáticas. Como resultado, pueden ser más precisos y menos ambiguos que la semántica dada en lenguaje natural. Sin embargo, a menudo se incluyen descripciones suplementarias de la semántica en lenguaje natural para ayudar a comprender las definiciones formales. Por ejemplo, la Norma ISO para Modula-2 contiene una definición de lenguaje tanto formal como natural en páginas opuestas.
Los lenguajes de programación cuya semántica se describe formalmente pueden obtener muchos beneficios. Por ejemplo:
- La semántica formal permite pruebas matemáticas de la corrección del programa;
- La semántica formal facilita el diseño de sistemas de tipos y pruebas sobre la solidez de esos sistemas de tipos;
- La semántica formal puede establecer estándares inequívocos y uniformes para la implementación de un lenguaje.
El soporte automático de herramientas puede ayudar a obtener algunos de estos beneficios. Por ejemplo, un comprobador de teoremas automatizado o un verificador de teoremas puede aumentar la confianza de un programador (o diseñador de lenguaje) en la exactitud de las demostraciones sobre programas (o el lenguaje mismo). El poder y la escalabilidad de estas herramientas varían ampliamente: la verificación formal completa es computacionalmente intensiva, rara vez se escala más allá de los programas que contienen algunos cientos de líneas [ cita requerida ] y puede requerir una considerable asistencia manual de un programador; las herramientas más ligeras, como los verificadores de modelos, requieren menos recursos y se han utilizado en programas que contienen decenas de miles de líneas; muchos compiladores aplican comprobaciones de tipo estático a cualquier programa que compilan.
Implementación de referencia
Una implementación de referencia es una implementación única de un lenguaje de programación designado como autorizado. El comportamiento de esta implementación se lleva a cabo para definir el comportamiento adecuado de un programa escrito en el lenguaje. Este enfoque tiene varias propiedades atractivas. Primero, es preciso y no requiere interpretación humana: las disputas sobre el significado de un programa pueden resolverse simplemente ejecutando el programa en la implementación de referencia (siempre que la implementación se comporte de manera determinista para ese programa).
Por otro lado, definir la semántica del lenguaje a través de una implementación de referencia también tiene varios inconvenientes potenciales. El principal de ellos es que combina las limitaciones de la implementación de referencia con las propiedades del lenguaje. Por ejemplo, si la implementación de referencia tiene un error, entonces ese error debe considerarse un comportamiento autorizado. Otro inconveniente es que los programas escritos en este lenguaje pueden depender de peculiaridades en la implementación de referencia, lo que dificulta la portabilidad en diferentes implementaciones.
Sin embargo, varios lenguajes han utilizado con éxito el enfoque de implementación de referencia. Por ejemplo, se considera que el intérprete de Perl define el comportamiento autorizado de los programas Perl. En el caso de Perl, el modelo de código abierto de distribución de software ha contribuido al hecho de que nadie ha producido otra implementación del lenguaje, por lo que los problemas relacionados con el uso de una implementación de referencia para definir la semántica del lenguaje son discutibles.
Banco de pruebas
Definir la semántica de un lenguaje de programación en términos de un conjunto de pruebas implica escribir una serie de programas de ejemplo en el lenguaje y luego describir cómo deben comportarse esos programas, tal vez escribiendo sus resultados correctos. Los programas, más sus resultados, se denominan "suite de pruebas" del lenguaje. Cualquier implementación de lenguaje correcta debe producir exactamente los resultados correctos en los programas de la suite de pruebas.
La principal ventaja de este enfoque de la descripción semántica es que es fácil determinar si una implementación de lenguaje pasa una serie de pruebas. El usuario puede simplemente ejecutar todos los programas en el conjunto de pruebas y comparar las salidas con las salidas deseadas. Sin embargo, cuando se usa solo, el enfoque del conjunto de pruebas también tiene grandes inconvenientes. Por ejemplo, los usuarios quieren ejecutar sus propios programas, que no forman parte del conjunto de pruebas; de hecho, una implementación de lenguaje que solo pudiera ejecutar los programas en su suite de prueba sería en gran medida inútil. Pero un conjunto de pruebas no describe, por sí mismo, cómo debería comportarse la implementación del lenguaje en ningún programa que no esté en el conjunto de pruebas; determinar ese comportamiento requiere cierta extrapolación por parte del implementador, y los diferentes implementadores pueden estar en desacuerdo. Además, es difícil utilizar un conjunto de pruebas para probar el comportamiento que se pretende o se permite que sea no determinista .
Por lo tanto, en la práctica común, los conjuntos de pruebas se utilizan solo en combinación con una de las otras técnicas de especificación del lenguaje, como una descripción en lenguaje natural o una implementación de referencia.
Ver también
- Referencia del lenguaje de programación
enlaces externos
Especificaciones de idioma
Algunos ejemplos de especificaciones lingüísticas oficiales o en borrador:
- Especificaciones escritas principalmente en matemáticas formales:
- La Definición de ML estándar, edición revisada : una definición formal en un estilo de semántica operativa .
- Esquema R5RS : una definición formal en un estilo de semántica denotacional
- Especificaciones escritas principalmente en lenguaje natural:
- Informe Algol 60
- Ada 95 manual de referencia
- Especificación del lenguaje Java
- Borrador de estándar C ++
- Especificaciones a través de la suite de pruebas:
- Especificación impulsada por la comunidad de facto de Ruby
Notas
- ^ Anuncio de una especificación para PHP , 30 de julio de 2014, Joel Marcey
- ^ "Una historia más corta de Algol68" . Archivado desde el original el 10 de agosto de 2006 . Consultado el 15 de septiembre de 2006 .
- ^ Milner, R .; M. Tofte ; R. Harper ; D. MacQueen (1997). Definición de NM estándar (revisada) . Prensa del MIT. ISBN 0-262-63181-4.
- ^ Kelsey, Richard; William Clinger; Jonathan Rees (febrero de 1998). "Sección 7.2 Semántica formal" . 5 Informe revisado sobre el esquema de lenguaje algorítmico . Consultado el 9 de junio de 2006 .
- ^ Jones, D. (2008). Formas de especificación de lenguaje (PDF) . Consultado el 23 de junio de 2012 .
- ^ William Pugh. El modelo de memoria de Java es fatalmente defectuoso. Simultaneidad: práctica y experiencia 12 (6): 445-455, agosto de 2000