4 puntos por GN⁺ 13 일 전 | 1 comentarios | Compartir por WhatsApp
  • Ada, nacida en medio del caos del software del Departamento de Defensa de EE. UU. en los años 70, es un lenguaje cuyo núcleo se basa en tipado estático fuerte y separación entre especificación e implementación
  • Mediante una estructura de paquetes y ocultamiento representacional, implementa una encapsulación completa, e influyó después en los sistemas de módulos de lenguajes modernos como Java, C# y Go
  • Tipos con restricciones semánticas, genéricos, concurrencia (task), y diseño por contrato son conceptos que Ada propuso décadas antes, y que luego heredaron Haskell, Rust y Swift, entre otros
  • SPARK Ada elimina incluso condiciones de carrera y errores lógicos mediante verificación formal, y se usa en ámbitos de alta confiabilidad como aviación, ferrocarriles y sistemas de defensa
  • Ada no es un lenguaje popular, pero como “el lenguaje que funciona correctamente en silencio”, sentó principios fundamentales del diseño de lenguajes de programación modernos

Contexto del nacimiento de Ada y su filosofía de diseño

  • A comienzos de los años 70, el Departamento de Defensa de EE. UU. (DoD) investigó una situación en la que más de 450 lenguajes y dialectos coexistían en sistemas de armas, logística y comunicaciones
    • Cada sistema tenía problemas de falta de interoperabilidad, imposibilidad de mantenimiento y ausencia de los autores originales
    • Esto provocó una crisis en la adquisición de software
  • El DoD no adoptó lenguajes existentes (COBOL, Fortran, PL/1, etc.), sino que pasó por un proceso de cinco años para definir requisitos
    • Los documentos evolucionaron de Strawman → Woodenman → Tinman → Ironman → Steelman
    • Steelman (1978) exigía separación explícita de interfaces, tipado estático fuerte, concurrencia incorporada, manejo consistente de excepciones, independencia de la máquina, legibilidad y capacidad de verificación
  • En la competencia de 1979 entre cuatro equipos (Green, Red, Blue, Yellow), fue elegido el equipo Green liderado por Jean Ichbiah, y el lenguaje recibió el nombre de Ada
    • El nombre fue puesto en honor a Ada Lovelace, simbolizando la intención del lenguaje

Estructura de paquetes y encapsulación

  • La estructura central de Ada es el paquete (package), donde la especificación (specification) y el cuerpo (body) están separados físicamente
    • La especificación es el contrato expuesto al exterior, el cuerpo es la implementación, y el compilador obliga la relación entre ambos
    • El código cliente no puede acceder a elementos que no estén en la especificación
  • Esta estructura fue el prototipo de los sistemas de módulos, y lenguajes posteriores la imitaron parcialmente
    • Java, Python, JavaScript, C, Go y Rust no logran implementar la separación estructural completa de Ada
  • Los tipos private exponen solo el nombre, mientras que su representación interna permanece completamente opaca
    • El cliente no puede conocer la estructura interna del tipo y solo puede usar las operaciones permitidas
    • Esto es un ocultamiento representacional más fuerte que el control de acceso private de Java
  • Java y C# evolucionaron gradualmente durante décadas en dirección al nivel de encapsulación de Ada

Sistema de tipos y restricciones semánticas

  • Ada define la distinción entre tipo y subtipo en sentido matemático
    • Ejemplo: type Age is range 0 .. 150 crea un tipo separado con una restricción de rango
    • El paso entre tipos incorrectos se detecta como error en tiempo de compilación
  • En 1983, el sistema de tipos de Ada era mucho más expresivo que el de C, Fortran o Pascal
    • Los tipos con restricciones semánticas ayudan a prevenir errores de dominio
  • El registro discriminado (discriminated record) es una estructura con campos distintos según el valor
    • Equivale a los tipos suma (sum type) o tipos de datos algebraicos (ADT) de los lenguajes modernos
    • Haskell, Rust, Swift, Kotlin y TypeScript introdujeron el mismo concepto décadas después

Genéricos y polimorfismo

  • Los genéricos (generic) de Ada son unidades que reciben como parámetros tipos, valores, subprogramas y paquetes
    • Implementan polimorfismo estático (parametric polymorphism) con verificación de tipos en compilación
  • C++ (1990), Java (2004), C# (2005) y Go (2022), entre otros, incorporaron funciones similares décadas después de Ada
    • Java pierde información de tipos en tiempo de ejecución por borrado de tipos (type erasure)
    • Ada conserva los tipos en tiempo de ejecución y además soporta parametrización de paquetes
  • Los genéricos de Ada ofrecen una expresividad al nivel del polimorfismo de orden superior (higher-kinded polymorphism)
    • Un concepto similar a las type classes de Haskell, los traits de Rust y los concepts de C++20

Modelo de concurrencia y seguridad

  • Ada incorporó desde 1983 concurrencia a nivel de lenguaje (task)
    • Mediante la declaración de task y el modelo de comunicación rendezvous, implementa paso de mensajes sin estado compartido
    • Los channels de Go pertenecen a la misma familia conceptual de CSP (Communicating Sequential Processes)
  • Ada 95 introdujo el objeto protegido (protected object)
    • Protege el acceso a los datos y se divide en procedure, function y entry
    • Ofrece condiciones de barrera automáticas y sincronización sin locks
  • SPARK Ada demuestra matemáticamente, mediante verificación formal, la ausencia de condiciones de carrera, excepciones, errores de rango y violaciones de precondiciones y postcondiciones
    • Mientras que el borrow checker de Rust solo garantiza seguridad de memoria, SPARK prueba incluso la consistencia lógica

Diseño por contrato y seguridad ante null

  • Ada 2012 integró los contratos (contracts) en el lenguaje
    • Permite especificar precondiciones (precondition), postcondiciones (postcondition) e invariantes de tipo (invariant)
    • La cadena de herramientas de SPARK los usa para demostración estática
  • Formalizó a nivel de lenguaje el concepto de Design by Contract de Eiffel (1986)
    • C++, Java, Python y Rust se han quedado en implementaciones parciales o a nivel de biblioteca
  • Ada 2005 introdujo los tipos not null, dando soporte a la exclusión de null en tiempo de compilación
    • Por defecto, garantiza una falla segura mediante excepción en tiempo de ejecución (Constraint_Error)
    • Un enfoque similar al de las referencias anulables de C# 8.0

Estructura del manejo de excepciones

  • Ada 83 fue el primero en introducir manejo estructurado de excepciones (structured exception handling)
    • Las excepciones se declaran antes de usarse, se manejan por ámbito y tienen reglas claras de propagación
  • Las checked exceptions de Java son una forma más desarrollada que en Ada, ya que obligan al llamador a declararlas
    • Ada permite libre propagación de excepciones
  • Rust elimina las excepciones y adopta un manejo de errores basado en el tipo Result
    • La contribución de Ada fue estructurar la propagación de excepciones y volverla predecible

Annex y estructura de estandarización

  • El estándar de Ada tiene una estructura de extensiones opcionales llamada Annex
    • Los Annex C~H definen funciones por áreas como sistemas, tiempo real, distribución, cálculo numérico y alta confiabilidad
    • Los compiladores deben obtener certificación independiente para cada Annex
  • La conformidad con el estándar se verifica mediante las pruebas ACATS de la ACAA
    • La estructura del estándar de Ada puede aprovecharse directamente para la certificación de software aeronáutico DO-178C
    • C/C++ también pueden certificarse, pero Ada es estructuralmente más adecuado

La influencia de Ada y el desequilibrio en su percepción

  • Ada fue un lenguaje impulsado por el gobierno, por lo que no recibió atención dentro de la cultura de Silicon Valley
    • En contraste con la preferencia cultural por sintaxis concisas basadas en C
  • Los casos de éxito de Ada (aviación, ferrocarriles, sistemas de defensa) tienen poca visibilidad precisamente porque no fallan
    • Los sistemas altamente confiables no generan debates ni incidentes
  • La dirección de evolución de los lenguajes modernos converge hacia principios que Ada ya había planteado
    • Separación entre especificación e implementación, verificación estática de tipos, concurrencia a nivel de lenguaje, seguridad basada en contratos, etc.
  • Ada sigue operando en sistemas de alta confiabilidad como aviones, ferrocarriles y naves espaciales, y permanece como “el lenguaje que funciona correctamente en silencio”

1 comentarios

 
GN⁺ 13 일 전
Comentarios en Hacker News
  • Me gusta Ada. Pero me sorprende que, al hablar del manejo de tipos, se haya omitido por completo a los lenguajes de la familia ML (ML, SML, CML, Caml, OCaml, etc.)
    Estos lenguajes admiten tipos estructurales a nivel del compilador. El problema de Ada era que, como PL/I, PHP o Perl, el propio lenguaje era demasiado grande y su sintaxis compleja. El artículo dice que eso era una ventaja, pero personalmente creo que las extensiones estándar separadas en Annex eran mucho mejores. Si el lenguaje base hubiera sido más pequeño y se hubiera apostado por los Annex, probablemente se habría usado más

    • En los lenguajes ML, el usuario no puede definir directamente tipos Integer/Floating point acotados. Uno de los rasgos centrales de Ada es justamente ese sistema de tipos. Cuando experimentas el sistema de tipos de Ada, te sorprende cuánto pueden mejorar la calidad y la confiabilidad del código
  • Una de las razones por las que Ada fue ignorado es que los compiladores costaban decenas de miles de dólares. En una época sin compiladores gratis ni de código abierto, otros lenguajes podían usarse sin pagar. Ese fue un factor decisivo

    • Ada no logró salir de su nicho por una combinación de razones. La complejidad del lenguaje y la tecnología de compiladores de la época hacían que no pudiera ejecutarse bien en las microcomputadoras de los 80. Intel incluso creó el i432 incorporando conceptos de Ada en hardware, pero el rendimiento fue pésimo. Luego las microcomputadoras dominaron el mundo y el legado de C y ensamblador continuó por más de 20 años
    • Yo usé Ada durante varios años, y que mis colegas usaran otros lenguajes como hobby no ayudó a su difusión. También era débil en manejo de cadenas y lento. En particular, el manejo de concurrencia era incómodo porque no usaba hilos del sistema operativo. Al final usamos las extensiones de tiempo real de HPUX y lo corrimos con varios procesos
    • Desde mediados de los 90 existía GNAT, y en esa época también eran comunes los compiladores comerciales. La razón de que Ada se estancara fue la percepción de que implicaba “sobrecarga innecesaria”. Es decir, tenía la reputación de que no había motivo para usarlo fuera del ámbito militar o de sistemas críticos de seguridad
    • GNU Ada Compiler(GNAT) se publicó por primera vez en 1995
    • En realidad, en los 80 la calidad de los compiladores era mala para cualquier lenguaje. Incluso GCC recién se volvió realmente usable hacia el final de esa etapa. Si usabas un lenguaje nuevo, era normal que el compilador todavía estuviera verde. C++ también estaba muy por detrás de Ada en ese entonces, y la “función matadora de C++” era básicamente que podía usarse como C. Quizá la historia habría sido distinta si Ada hubiera ofrecido un modo de compatibilidad con Pascal
  • Mientras leía el artículo, tanto Ada como el texto en sí me parecieron interesantes, pero saltaron a la vista varios errores de hecho. Por ejemplo, decía que solo Ada separa por completo implementación y especificación, pero JavaScript también puede definir elementos privados con módulos ES6. La explicación sobre la visibilidad private de Java también era incorrecta. Por errores así, el artículo pierde credibilidad

    • En Ada, si defines un tipo private, desde fuera no se puede acceder a los campos internos. En cambio, en JavaScript se pueden agregar o eliminar propiedades libremente a cualquier objeto. O sea, el nivel de protección en tiempo de compilación de Ada no se puede comparar con JS
    • En Java se puede acceder a miembros privados mediante reflection. Con setAccessible(true) incluso se puede modificar el interior de String
    • Me pareció llamativa la idea de que, cuando un LLM escribe para lectores humanos, funciona como una especie de amnesia de Gell-Mann
  • En general el artículo estuvo bien, pero se volvió cansado por la repetición constante de frases como “el lenguaje X incorporó esta función después que Ada”. Con ejemplos de código habría sido mucho más convincente

    • En realidad, muchas de las funciones de Ada fueron tomadas de lenguajes anteriores (PASCAL, CLU, MODULA, CSP, etc.). Más que conceptos totalmente nuevos, fueron una integración de ideas ya probadas
    • Algunos de los conceptos que el texto afirma que Ada introdujo primero en realidad se implementaron de otra manera. Por eso hacían falta ejemplos comparativos
    • Este artículo no dice “Ada es lo máximo”, sino que muestra qué tipo de diseño hizo Ada en favor de la seguridad y la confiabilidad. La comparación por años tiene sentido en ese contexto
    • Le pedí a Claude un código de demostración en Ada y estuvo bastante bien. Conocía Ada desde hace tiempo, pero al probarlo sentí un poco de FOMO
    • Desde la perspectiva de un desarrollador de Ada, este patrón de comparaciones puede sentirse agotador después de tantos años
  • Esta cuenta de Twitter fue creada en abril de 2026 y no indica quién es el autor. Ha mostrado una productividad enorme en muy poco tiempo, y resulta interesante que no revele su identidad

    • También hay quien opina que no tiene autor porque es un bot
  • La afirmación de que “todos los lenguajes agregaron sum types en los últimos 20 años, pero Ada los tuvo desde el principio” es cierta, pero su origen no está en Ada. El lenguaje Hope o NPL aparecieron antes

    • En realidad, el origen de los sum types está en el artículo de 1964 de John McCarthy, “Definition of new data types in ALGOL X”. Él propuso la palabra clave UNION, y luego la idea evolucionó en ALGOL 68, Hope, Miranda y otros. El union de C es distinto de ese concepto
  • Me gustó tanto el artículo que quise creer que no lo había escrito una IA, pero la velocidad con la que publicaba en Twitter me pareció sospechosa

    • El texto se sentía un poco verboso y repetitivo, así que daba vibra de IA
    • Hoy en día hay muchas herramientas de IA para reescribir entradas de blog automáticamente, así que eso despierta sospechas
    • A mí también me gustó leerlo, pero recién después de ver 110 rayas largas pensé: “¿y si es IA?”. Es triste que incluso las entradas de blog ahora se lean con filtro de alfabetización mediática
    • Yo también escribí 50 textos en 3 años, pero la mayoría siguen sin publicarse. Tal vez este autor estaba en una situación parecida y recién hace poco se animó a publicar. Entiendo lo frustrante que debe ser que te confundan con una IA
    • Si una IA pudiera escribir textos de este nivel, valdría la pena aunque me hiciera perder tiempo
  • La Fuerza Aérea de EE. UU. originalmente quería usar Ada, pero como el desarrollo se retrasó terminó usando JOVIAL. Yo hice mi primer proyecto en JOVIAL en 1981, y en ese momento Ada todavía estaba en fase de especificación

    • JOVIAL era un lenguaje derivado de IAL, antecesor de ALGOL 60, e influyó en los requisitos iniciales del desarrollo de Ada (STRAWMAN~STEELMAN). Después Ada mejoró funciones de JOVIAL e introdujo innovaciones como la declaración explícita de parámetros in/out. Gracias a eso no necesitó cosas como constructores de copia o move semantics complejas al estilo de C++
  • En la página principal del sitio aparece la frase “esto no es una postura, es una propuesta”, y a partir de eso alguien afirma que es un sitio escrito por IA

    • Pero esa frase no es prueba de que lo haya escrito una IA
  • El artículo decía que “el sistema de módulos de JavaScript no puede ocultar la representación interna de un tipo como Ada”, pero en realidad en los módulos de JS, si no exportas algo, queda suficientemente oculto. Me pregunté si Ada realmente tiene alguna ventaja especial ahí

    • Si lo miras desde TypeScript, los objetos de JS todavía permiten agregar o modificar propiedades desde fuera. En Ada, con una instancia de tipo private, no es posible manipularla fuera de la API definida
    • Para un ejemplo concreto, se puede consultar este comentario