¿Por qué deberías usar el lenguaje Ada para programar tu sistema?



El lenguaje de programación Ada nació a mediados de la década de 1970 cuando el Departamento de Defensa de los EE. UU. Y el Departamento de Defensa británico decidieron reemplazar cientos de lenguajes de programación especializados para sistemas informáticos integrados, que se usaban cada vez más en proyectos militares. El lenguaje Ada se desarrolló de tal manera que era el único lenguaje capaz de trabajar en todos estos sistemas integrados y, al mismo tiempo, proporcionar confiabilidad y rendimiento a un nivel no peor que los especializados.

Después de la actualización de 1995, el lenguaje se adaptó para sistemas de propósito general, agregando programación orientada a objetos, sin perder de vista los valores clave: confiabilidad, facilidad de soporte y eficiencia. Hoy en día, el software escrito en Ada forma la base no solo de equipos militares, sino también de proyectos comerciales en el campo de la aviónica y los sistemas de control de tráfico aéreo. El código para Ada controla misiles como Arian-4 y 5, muchos satélites e innumerables otros sistemas en los que pequeños fallos pueden tener serias consecuencias.

Quizás Ada sea adecuada para usar en su próximo proyecto integrado.

Planificación de calidad militar


Para seleccionar un nuevo lenguaje de programación, el Ministerio de Defensa reunió un " Grupo de Trabajo de Idiomas de Alto Orden (HOLWG)], formado por expertos militares y científicos cuya tarea era compilar una lista de consultas y seleccionar los idiomas candidatos. Como resultado, el llamado " Peticiones de Stillman ":

Los puntos principales de las solicitudes fueron:

  • Un flujo de trabajo flexible de uso general que se adapta a las necesidades de las aplicaciones informáticas integradas.
  • Fiabilidad El lenguaje debe facilitar el diseño y desarrollo de programas confiables.
  • Facilidad de soporte. El código debe ser legible y las soluciones de software claras.
  • Facilidad de producir código eficiente. Debería ser posible identificar fácilmente diseños ineficientes.
  • Sin complejidad innecesaria. La estructura semántica debe ser coherente y minimizar el número de conceptos.
  • Independencia del automóvil. El idioma no debe estar vinculado a ningún detalle del sistema operativo o hardware.
  • Definición completa Todas las partes del lenguaje deben definirse total y explícitamente.

El informe concluyó con la opinión de que la primera línea de defensa contra los problemas de software es evitar que los programadores cometan errores. Al eliminar la posibilidad de cometer un error sutil, por ejemplo, mediante conversiones de tipo implícitas u otras construcciones peligrosas, automáticamente hacemos el código más seguro y facilitamos su soporte.

El grupo concluyó que, aunque ninguno de los idiomas existentes en ese momento era adecuado para las necesidades del Ministerio de Defensa, era bastante realista crear un nuevo idioma que se adaptara a todos estos problemas. Cuatro diseñadores lo lograron. El proceso de selección intermedia seleccionó los dos métodos de trabajo más adecuados y, como resultado, solo un idioma ganó la competencia y recibió el nombre de " Ada ".



Protección predeterminada incorporada


El sistema de tipos en el Infierno no es solo estricto, a veces se lo denomina súper estricto porque no permite ninguna conversión de tipo implícita. Tome, por ejemplo, este fragmento de código C:

typedef uint32_t myInt; myInt foo = 42; uint32_t bar = foo; 

Este es un código válido; compilará, iniciará y producirá un resultado obvio que indica la respuesta a la pregunta principal de la vida, el universo y todo eso. En el infierno, esto no funcionará:

 type MyInt is Integer; foo: MyInt; bar: Integer; foo := 42; bar := foo; 

El compilador arrojará un error, porque Integer y MyInt no son lo mismo. La principal ventaja de este enfoque es que si el programador cambia la definición de tipo, miles de conversiones de tipo implícitas en toda la base de código no harán explotar el programa. En cambio, los tipos deben emitirse explícitamente; esto promueve un buen código, evitando la confusión de los tipos que son "bastante similares".

Cualquier programador atrapado en un pantano de una mezcla de definiciones estándar de los tipos C, Linux y Win32 puede apreciar la falta de necesidad de rebuscar en innumerables páginas de documentación y código mal formateado para comprender qué typedef o macro contiene una definición real de algo que solo que impidió la compilación o se arrastró durante la depuración.



Ada agrega capas adicionales de protección en las comprobaciones en las etapas de compilación y lanzamiento. En Ada, el programador debe especificar explícitamente las declaraciones de cierre para los bloques y los límites en los que debe ajustarse el valor de la variable. Ada no define tipos estándar como int o float, pero requiere que el programador cree tipos con un rango específico desde el principio. Esto también es cierto para las cadenas: con la excepción de cadenas ilimitadas, todas las cadenas tienen una longitud fija.

En la etapa de operación, puede verificar errores como acceso incorrecto a la memoria, desbordamientos del búfer, exceder los límites establecidos, errores ± 1, acceso a la matriz. Luego se pueden procesar de forma segura, en lugar de descartar toda la aplicación.

Ada implementa un modelo de tipos de referencia en lugar de punteros de bajo nivel. Cada grupo de memoria procesa cada tipo de referencia, ya sea de forma predeterminada, o un programador específico, si es necesario, para trabajar con implementaciones de memoria NUMA más exóticas. Un programador nunca tiene que acceder a la memoria directamente; debe usar un controlador de agrupación de memoria.

Finalmente, el compilador o el programa en tiempo de ejecución decide cómo pasar datos hacia o desde la función. Y aunque es necesario indicar la dirección de transmisión de cada parámetro ('in', 'out' o 'in out'), el compilador o el programa toma la decisión final sobre si los datos se transmiten a través de registros, montones o por referencia en tiempo de ejecución, pero No es un programador. Esto evita problemas de desbordamiento de pila.

El perfil de Ravenscar y el dialecto SPARK son subconjuntos de Ada, y este último se centra en los contratos. Con el tiempo, las características de estos subconjuntos se han transferido a la especificación del idioma principal.

Ada programando hoy


ANSI estableció la especificación Ada 83 en 1983. Luego se lanzó el Intel 80286 y el Motorola 68000 tenía solo cuatro años. Fue el comienzo de las computadoras domésticas, así como una transición torpe de los años 70 a los 80, cuando la popularidad de los microcontroladores comenzó a crecer. Imagine el microcontrolador Intel 8051 y su impresionante EPROM de 4kb y 128B de RAM.



Los microcontroladores que son populares hoy en día son muchas veces más potentes que los de 1983. Puede tomar cualquier ARM, AVR, RISC-V, etc. (o el kit Lego Mindstorms NXT) y comience a desarrollarlo utilizando las mismas herramientas basadas en C. No es sorprendente que el popular compilador GNAT Ada se base en GCC. También en desarrollo dentro del proyecto DragonEgg hay herramientas basadas en LLVM.

Hay dos versiones de las herramientas Ada basadas en GCC. La opción AdaCore es compatible comercialmente, pero tiene sus propias características. La opción Free Software Foundation es naturalmente gratuita y es comparable en funcionalidad a AdaCore.

Para comenzar fácilmente, use el IDE (GPS) de GNAT Programming Studio , que se incluye con AdaCore (una copia en Github ), o escriba el código en un editor de texto y compílelo manualmente, o use Makefiles. El kit de herramientas aquí es un poco más complicado que el de C o C ++, pero el desarrollo se ve facilitado por la utilidad gnatmake, que incluye todas las herramientas, y funciona aproximadamente como GCC.



Un ejemplo de un proyecto pequeño pero no trivial en Ada escrito por su humilde servidor como analizador de argumentos de línea de comando. Allí encontrará el Makefile ubicado en la carpeta ada / project, donde se definen las carpetas donde puede encontrar los archivos de especificación del paquete (.ads) y los paquetes mismos (.adb).

Estos archivos corresponden aproximadamente a archivos con encabezados y código de C y C ++, sin embargo, también tienen diferencias importantes. A diferencia de C, Ada no tiene un preprocesador y no combina código y encabezados para crear archivos compilados. En cambio, hay un enlace al nombre del paquete especificado en la especificación. El nombre del archivo .ads tampoco tiene que coincidir con el nombre del paquete. Esto proporciona una gran flexibilidad y evita problemas comunes en C con dependencia cíclica o la necesidad de vincular encabezados en un orden específico.

A donde ir ahora


Después de descargar el kit de herramientas GNAT, iniciar GPS o Vim / Emacs, y durante un tiempo mirando el cursor parpadeante en una página en blanco, puede pensar por dónde empezar. Afortunadamente, recientemente cubrimos un proyecto basado en Ada utilizando el núcleo PicoRV32 RISC-V. Utiliza el popular ICE40LP8K CPLD, que es compatible con FPGA de código abierto como Yosys.



En términos de documentación, hay artículos introductorios para principiantes diseñados para desarrolladores de Java y C ++, una referencia de AdaCore , una referencia de WikiBooks y, por supuesto, documentación de Programación en Ada 2012 . Estas son quizás las referencias más completas, con la excepción del Manual de referencia del lenguaje Ada 2012 (LRM) de 945 páginas.

El lenguaje Ada, aunque es bastante raro para los amantes de la programación, es un lenguaje completamente abierto con herramientas de desarrollo confiables con soporte comercial, y se utiliza para crear software para todo, desde misiles balísticos intercontinentales y F-15 hasta firmware de dispositivos médicos. Aunque este es un lenguaje bastante complicado, si va más allá de los límites básicos, definitivamente debe incluirse en la lista de idiomas que ha utilizado en sus proyectos, incluso para que su currículum se vea mejor.

Source: https://habr.com/ru/post/469671/


All Articles