✈️ Ada — 1983

⬅️ Atlas · 🧟 Lenguajes que siguen vivos · 📚 Índice de clases

El lenguaje que no puede fallar. Si vuelas, si tomas un metro automático o si un satélite mantiene su órbita, hay una probabilidad razonable de que Ada esté ejecutándose. Es un nicho pequeño y es, seguramente, el nicho con las consecuencias más graves.

🎯 Por qué está en este programa

Criterio de inclusión: Ada se ejecuta hoy en aviónica, espacio, ferrocarril y defensa, con revisión del estándar en 2022 y un ecosistema activo (GNAT, Alire, SPARK). Es un nicho pequeño, pero es el nicho donde un fallo se cuenta en vidas.

Entra porque deja a la vista un concepto que el núcleo esconde: que el tipo puede llevar encima una regla del dominio, no solo un tamaño de máquina. En casi todo el núcleo, un descuento es un float y "entre 0 y 1" es un comentario o un if que alguien recordó escribir. En Ada, range 0.0 .. 1.0 forma parte del tipo y el programa se niega a continuar si se viola. Es la versión llevada al extremo de lo que Rust hace con la nulabilidad y TypeScript con los tipos literales — y verla en Ada aclara de dónde viene esa idea.

Año 1983 (MIL-STD-1815); revisiones 95, 2005, 2012, 2022
Autoría Equipo de Jean Ichbiah en CII Honeywell Bull, por encargo del DoD de EE. UU.
Familia Pascal / ALGOL, rama de sistemas críticos
Paradigma Imperativo, modular, concurrente y OO (desde Ada 95)
Tipado Estático, fuerte y nominal, con subtipos y rangos comprobados
Memoria Pila y montículo con control explícito; sin recolector obligatorio
Ejecución Compilado a nativo, con comprobaciones en tiempo de ejecución activables
Estado 🟢 Nicho pequeño, importancia extrema — aviónica, defensa, espacio, ferrocarril

📜 Historia

A mediados de los 70 el Departamento de Defensa de Estados Unidos hizo un inventario y encontró que sus sistemas embebidos usaban más de 450 lenguajes y dialectos distintos. Cada proveedor traía el suyo; nada era reutilizable, nada era auditable y formar gente era carísimo. En 1975 se creó un grupo de trabajo para definir un lenguaje único, y en 1977 se convocó un concurso internacional con propuestas anónimas identificadas por colores. En 1979 ganó la propuesta Verde, del equipo de Jean Ichbiah.

El lenguaje se llamó Ada en honor a Ada Lovelace, y su estándar militar recibió el número MIL-STD-1815: 1815 es el año de nacimiento de Lovelace. Es probablemente el número de norma más deliberado de la historia de la informática.

La evolución fue quitando rigidez sin quitar garantías. Ada 95 fue el primer lenguaje orientado a objetos con estándar ISO. Ada 2005 añadió interfaces y mejoras de tiempo real. Ada 2012 introdujo lo que hoy es su sello: los contratos —precondiciones, postcondiciones e invariantes de tipo— escritos como parte de la declaración y comprobables por el compilador o en ejecución. Ada 2022 es la revisión vigente.

En paralelo creció SPARK, un subconjunto de Ada con anotaciones que permite demostrar matemáticamente la ausencia de errores en tiempo de ejecución: no que los tests pasen, sino que ciertos fallos son imposibles. Es de las pocas tecnologías de verificación formal que se usa de verdad en industria.

🏭 Dónde sobrevive hoy

🧠 Por qué no ha muerto

1. El sistema de tipos convierte errores de dominio en errores de compilación. Ada permite declarar tipos con rango, y comprobarlos. Esto no es un comentario ni un assert:

type Altitud_Pies  is range 0 .. 60_000;
type Velocidad_Nudos is range 0 .. 900;

A : Altitud_Pies  := 35_000;
V : Velocidad_Nudos := 450;
-- A := A + V;  --  ERROR DE COMPILACIÓN: son tipos distintos

Dos enteros con la misma representación pero distinto significado no son intercambiables. Sumar pies a nudos no compila. En C, en Python o en JavaScript, esa suma es perfectamente válida y perfectamente absurda. La pérdida de la sonda Mars Climate Orbiter en 1999 fue exactamente ese error —libras-fuerza contra newtons— en un sistema que no era Ada.

2. Las comprobaciones son parte del lenguaje, no de la disciplina del equipo. Índices fuera de rango, desbordamiento, desreferencia nula: Ada los detecta y lanza una excepción en lugar de producir comportamiento indefinido. Se pueden desactivar (pragma Suppress) cuando el rendimiento lo exija, pero la decisión es explícita y queda escrita.

3. La concurrencia está en el lenguaje. Las tareas (task), las citas (rendezvous) y los objetos protegidos son construcciones del lenguaje, no de una biblioteca. El perfil Ravenscar define un subconjunto de concurrencia con comportamiento temporal analizable, que es lo que permite certificar un sistema de tiempo real: no basta con que funcione, hay que poder demostrar que siempre cumple sus plazos.

4. Legibilidad como requisito de certificación. El diseño prioriza al lector sobre el escritor —begin/end con nombre, sin abreviaturas crípticas— porque el código de un avión lo audita gente que no lo escribió, años después.

5. Reescribirlo requeriría recertificar. Y la certificación de un sistema crítico cuesta más que el desarrollo.

La lección de Ariane 5. El fallo del vuelo 501 en 1996 se cita a veces como un fallo de Ada. Fue lo contrario: una conversión de un real de 64 bits a un entero de 16 desbordó, Ada detectó el desbordamiento y lanzó la excepción prevista. El defecto fue de ingeniería de sistemas —se reutilizó código de Ariane 4 con las comprobaciones desactivadas por rendimiento, en un cohete con una trayectoria distinta— y de gestión del fallo. El lenguaje avisó; el diseño no supo qué hacer con el aviso.

🔄 Lo que se ha modernizado

⚙️ Cómo se ejecuta hoy

# GNAT, el compilador Ada de GCC
sudo apt-get install -y gnat

# El nombre del fichero DEBE coincidir con el de la unidad: total_venta.adb
gnatmake total_venta.adb
echo "15000 2 0.10" | ./total_venta
# Total: 27000.00

Herramientas. GNAT (AdaCore, basado en GCC) es el compilador dominante, con edición libre (GNAT FSF, en las distribuciones) y comercial (GNAT Pro, con soporte para certificación). gprbuild es el sistema de construcción por proyectos, y Alire (alr) es el gestor de paquetes moderno, equivalente a cargo. Para verificación formal, GNATprove sobre SPARK.

🧪 El programa de la clase 041 en Ada

with Ada.Text_IO;            use Ada.Text_IO;
with Ada.Long_Float_Text_IO; use Ada.Long_Float_Text_IO;

procedure Total_Venta is

   --  El tipo dice lo que el negocio permite, no solo lo que la máquina guarda.
   subtype Descuento_T is Long_Float range 0.0 .. 1.0;

   Precio, Cantidad : Long_Float;
   Descuento        : Descuento_T;
   Total            : Long_Float;

begin
   Get (Precio);
   Get (Cantidad);
   Get (Descuento);          --  un 1.5 aquí levanta Constraint_Error

   Total := Precio * Cantidad * (1.0 - Descuento);

   Put ("Total: ");
   Put (Total, Fore => 1, Aft => 2, Exp => 0);
   New_Line;
end Total_Venta;

Recorrido, línea a línea.

Compáralo con la versión en C de la misma clase: el mismo cálculo, pero aquí el rango del descuento está en el tipo, y ni el compilador ni el lector tienen que confiar en que alguien lo validó.

🔍 Qué reconocer si vienes de otro lenguaje

Si conoces… En Ada es…
int x = 5; X : Integer := 5; — el nombre primero, := para asignar
== = (comparación); := es la asignación, como en Pascal
struct record
enum type Color is (Rojo, Verde, Azul); — un tipo de verdad, no un entero
typedef de C subtype (compatible) frente a type (incompatible a propósito)
Genéricos / plantillas generic — instanciados explícitamente, sin sorpresas
throw / try raise / exception when ... =>
Hilos y mutex task y protected — en el lenguaje, no en una librería
assert with Pre => ..., with Post => ..., with Type_Invariant => ...
1000000 1_000_000 — el subrayado como separador, idea que Ada popularizó

⚠️ Errores comunes al leerlo

📚 Fuentes y bibliografía


⏮️ Volver al Atlas · 🧟 Los lenguajes que siguen vivos · 🔗 Relacionadas: Pascal · Delphi / Object Pascal · Fortran