4 pontos por GN⁺ 13 일 전 | 1 comentários | Compartilhar no WhatsApp
  • Nascida em meio ao caos de software do Departamento de Defesa dos EUA nos anos 1970, Ada é uma linguagem centrada em tipagem estática forte e separação entre especificação e implementação
  • Por meio de estrutura em pacotes e ocultação representacional, implementa encapsulamento completo e depois influenciou sistemas de módulos de linguagens modernas como Java, C# e Go
  • Tipos com restrições semânticas, genéricos, concorrência (task), design por contrato e outros são conceitos que Ada apresentou décadas antes, depois herdados por Haskell, Rust e Swift
  • SPARK Ada elimina até corridas de dados e erros lógicos por meio de verificação formal, sendo usada em áreas de alta confiabilidade como aviação, ferrovias e sistemas de defesa
  • Ada não é uma linguagem popular, mas, como uma “linguagem que funciona corretamente em silêncio”, fornece os princípios fundamentais do design de linguagens de programação modernas

Contexto de nascimento de Ada e filosofia de projeto

  • No início dos anos 1970, o Departamento de Defesa dos EUA (DoD) investigou uma situação em que mais de 450 linguagens e dialetos coexistiam em sistemas de armas, logística e comunicação
    • Cada sistema tinha problemas de falta de interoperabilidade, impossibilidade de manutenção e ausência dos autores originais
    • Isso levou a uma crise na aquisição de software
  • Em vez de adotar linguagens existentes (COBOL, Fortran, PL/1 etc.), o DoD passou por um processo de 5 anos definindo requisitos
    • Os documentos evoluíram de Strawman → Woodenman → Tinman → Ironman → Steelman
    • O Steelman (1978) exigia separação explícita de interfaces, tipagem estática forte, concorrência embutida, tratamento consistente de exceções, independência de máquina, legibilidade e verificabilidade
  • Na competição entre 4 equipes em 1979 (Green, Red, Blue, Yellow), a equipe Green liderada por Jean Ichbiah foi escolhida, e a linguagem recebeu o nome Ada
    • O nome foi dado em homenagem a Ada Lovelace, simbolizando a intenção da linguagem

Estrutura em pacotes e encapsulamento

  • A estrutura central de Ada é o pacote (package), em que specification e body são separados fisicamente
    • A specification é o contrato exposto externamente; o body é a implementação, e o compilador impõe a relação entre ambos
    • O código cliente não pode acessar elementos que não estejam na specification
  • Essa estrutura é um protótipo de sistema de módulos, posteriormente imitado parcialmente por outras linguagens
    • Java, Python, JavaScript, C, Go e Rust não conseguem implementar a separação estrutural completa de Ada
  • Tipos private expõem apenas o nome, enquanto a representação interna permanece totalmente opaca
    • O cliente não pode conhecer a estrutura interna do tipo e só pode usar as operações permitidas
    • Isso é uma forma de ocultação representacional mais forte que o controle de acesso private do Java
  • Java e C# evoluíram gradualmente ao longo de décadas em direção a um encapsulamento no nível de Ada

Sistema de tipos e restrições semânticas

  • Ada define a distinção entre tipo e subtipo em sentido matemático
    • Ex.: type Age is range 0 .. 150 cria um tipo separado com restrição de faixa
    • Passagens entre tipos incorretos são detectadas como erro em tempo de compilação
  • Em 1983, o sistema de tipos de Ada já tinha poder expressivo muito superior ao de C, Fortran e Pascal
    • Tipos com restrições semânticas ajudam a prevenir erros de domínio
  • Registros discriminados (discriminated record) são estruturas que têm campos diferentes conforme o valor
    • Isso equivale aos sum types ou tipos algébricos de dados (ADT) das linguagens modernas
    • Haskell, Rust, Swift, Kotlin e TypeScript adotaram o mesmo conceito décadas depois

Genéricos e polimorfismo

  • Os genéricos (generic) de Ada são unidades que recebem tipos, valores, subprogramas e pacotes como parâmetros
    • Implementam polimorfismo estático (parametric polymorphism) com verificação de tipos em compilação
  • C++ (1990), Java (2004), C# (2005) e Go (2022) introduziram recursos semelhantes décadas depois de Ada
    • Java usa type erasure, perdendo informações de tipo em tempo de execução
    • Ada preserva os tipos em runtime e ainda suporta parametrização de pacotes
  • Os genéricos de Ada oferecem expressividade em nível de higher-kinded polymorphism
    • Conceito semelhante a type classes do Haskell, traits do Rust e concepts do C++20

Modelo de concorrência e segurança

  • Desde 1983, Ada traz concorrência em nível de linguagem (task) embutida
    • Com declarações task e o modelo de comunicação rendezvous, implementa passagem de mensagens sem estado compartilhado
    • Os channels de Go pertencem à mesma linhagem conceitual de CSP (Communicating Sequential Processes)
  • Ada 95 introduziu o protected object
    • Ele protege o acesso aos dados e os distingue em procedure, function e entry
    • Fornece condições de barreira automáticas e sincronização sem lock
  • SPARK Ada prova matematicamente, por meio de verificação formal, a ausência de corridas de dados, exceções, erros de faixa e violações de pré e pós-condições
    • Enquanto o borrow checker do Rust garante apenas segurança de memória, o SPARK prova até a consistência lógica

Design por contrato e segurança contra null

  • Ada 2012 integrou contratos (contracts) à linguagem
    • Permite declarar precondition, postcondition e type invariant
    • A cadeia de ferramentas do SPARK usa isso em provas estáticas
  • O conceito de Design by Contract do Eiffel (1986) foi formalizado em nível de linguagem
    • C++, Java, Python e Rust permanecem em implementações parciais ou no nível de bibliotecas
  • Ada 2005 introduziu tipos not null, oferecendo exclusão de null em tempo de compilação
    • O padrão ainda garante falha segura por meio da exceção em runtime (Constraint_Error)
    • Abordagem semelhante às nullable references do C# 8.0

Estrutura de tratamento de exceções

  • Ada 83 introduziu pela primeira vez o tratamento estruturado de exceções
    • Exceções são declaradas antes do uso, tratadas por escopo, com regras claras de propagação
  • As checked exceptions do Java são uma forma mais evoluída em relação a Ada, exigindo que o chamador declare as exceções
    • Ada permite livre propagação de exceções
  • Rust remove exceções e adota tratamento de erros baseado no tipo Result
    • A contribuição de Ada foi estruturar a propagação de exceções e torná-la previsível

Annex e estrutura de padronização

  • O padrão de Ada tem uma estrutura de extensões opcionais chamada Annex
    • Os Annex C~H definem recursos por área, como sistemas, tempo real, distribuição, numérico e alta confiabilidade
    • Compiladores precisam receber certificação independente para cada Annex
  • A conformidade com o padrão é verificada pelos testes ACATS da ACAA
    • A estrutura padrão de Ada pode ser usada diretamente na certificação de software aeronáutico DO-178C
    • C/C++ também podem obter a mesma certificação, mas Ada é estruturalmente mais adequada

Influência de Ada e desequilíbrio de percepção

  • Ada, por ser uma linguagem impulsionada pelo governo, não recebeu atenção no ecossistema cultural do Vale do Silício
    • Em contraste com a preferência por sintaxe enxuta baseada em C
  • Os casos de sucesso de Ada (aviação, ferrovias, sistemas de defesa) têm baixa visibilidade justamente por não falharem
    • Sistemas altamente confiáveis não geram discussões nem incidentes
  • A direção de evolução das linguagens modernas converge para princípios que Ada já havia apresentado
    • Como separação entre especificação e implementação, verificação estática de tipos, concorrência em nível de linguagem e segurança baseada em contratos
  • Ada continua em operação em sistemas de alta confiabilidade como aeronaves, ferrovias e espaçonaves, permanecendo como uma “linguagem que funciona corretamente em silêncio”

1 comentários

 
GN⁺ 13 일 전
Comentários do Hacker News
  • Eu gosto de Ada. Mas, ao falar de tratamento de tipos, me surpreendeu que tenham deixado totalmente de fora as linguagens da família ML (ML, SML, CML, Caml, OCaml etc.)
    Essas linguagens dão suporte a tipos estruturais no nível do compilador. O problema de Ada era que, como PL/I, PHP e Perl, a própria linguagem era grande demais e a sintaxe complexa. O texto diz que isso era uma vantagem, mas, pessoalmente, acho que as extensões padronizadas separadas em Annex eram muito melhores. Se o núcleo da linguagem tivesse sido menor e o foco fosse mais nos Annex, acho que ela teria sido mais amplamente usada

    • Nas linguagens ML, o usuário não pode definir diretamente tipos Integer/Floating point limitados. Um dos recursos centrais de Ada é justamente esse sistema de tipos. Quando você experimenta o sistema de tipos de Ada, se surpreende com o quanto a qualidade e a confiabilidade do código aumentam
  • Um dos motivos de Ada ter sido ignorada foi que o preço dos compiladores era de dezenas de milhares de dólares. Numa época sem compiladores gratuitos ou open source, outras linguagens podiam ser usadas de graça. Esse foi um fator decisivo

    • Ada não conseguiu sair do nicho por uma combinação de fatores. A complexidade da linguagem e a tecnologia de compiladores da época não permitiam que ela rodasse direito nos microcomputadores dos anos 1980. A Intel chegou a criar o i432, incorporando conceitos de Ada no hardware, mas o desempenho era péssimo. Depois disso, como os microcomputadores passaram a dominar o mundo, o legado de C e assembly continuou por mais de 20 anos
    • Usei Ada por alguns anos, mas o fato de meus colegas usarem outras linguagens como hobby não ajudou na difusão de Ada. O processamento de strings também era fraco, e a velocidade era baixa. Em especial, o tratamento de concorrência era incômodo porque não usava threads do SO. No fim, usamos a extensão de tempo real do HPUX para rodar em vários processos
    • Desde meados dos anos 90 já existia o GNAT, e naquela época compiladores comerciais também eram comuns. O que travou Ada foi a percepção de que havia “overhead desnecessário”. Ou seja, havia a reputação de que não havia motivo para usá-la fora de sistemas militares ou de segurança
    • GNU Ada Compiler(GNAT) foi lançado pela primeira vez em 1995
    • Na verdade, nos anos 80 a qualidade dos compiladores era ruim em qualquer linguagem. Até o GCC só ficou realmente utilizável mais para o fim da década. Ao usar uma linguagem nova, era natural que o compilador ainda fosse imaturo. O C++ também estava bem atrás de Ada naquela época, e o “recurso matador do C++” era, na prática, poder ser usado como C. Se Ada tivesse oferecido um modo de compatibilidade com Pascal, talvez a história tivesse sido diferente
  • O texto e o próprio Ada me pareceram interessantes, mas alguns erros factuais chamaram atenção. Por exemplo, dizia que só Ada separa completamente implementação e especificação, mas o JavaScript também permite definir elementos privados em módulos ES6. A explicação sobre a visibilidade private em Java também estava errada. Esses erros diminuem a credibilidade do texto

    • Em Ada, quando você define um tipo private, não é possível acessar os campos internos de fora. Já em JavaScript, qualquer objeto pode receber ou perder propriedades livremente. Ou seja, o nível de proteção em tempo de compilação de Ada é incomparável ao de JS
    • Em Java, é possível acessar membros private via reflection. Com setAccessible(true), dá até para modificar o interior de String
    • Achei marcante a ideia de que, quando um LLM escreve para leitores humanos, isso funciona como uma espécie de amnésia de Gell-Mann
  • No geral o texto era bom, mas a repetição constante de frases como “a linguagem X ganhou esse recurso depois de Ada” ficou cansativa. Se houvesse exemplos de código, teria sido bem mais convincente

    • Na verdade, muitos recursos de Ada foram emprestados de linguagens anteriores (PASCAL, CLU, MODULA, CSP etc.). Mais do que conceitos totalmente novos, foi o resultado da integração de ideias já validadas
    • Parte dos conceitos que o texto diz que Ada introduziu primeiro, na prática, foi implementada de forma diferente. Por isso faltaram exemplos comparativos
    • Este texto não está dizendo “Ada é a melhor”; ele mostra quais escolhas de projeto Ada fez em prol de segurança e confiabilidade. Nesse contexto, comparar anos faz sentido
    • Pedi ao Claude um código de demonstração em Ada e o resultado foi bem bom. Eu já conhecia Ada havia muito tempo, mas depois de experimentar senti até FOMO
    • Do ponto de vista de quem desenvolve em Ada, esse padrão de comparação pode soar cansativo por ter se repetido durante tantos anos
  • Esta conta no Twitter foi criada em abril de 2026 e não indica quem é o autor. Em pouco tempo mostrou uma produtividade enorme, e é curioso que o nome não tenha sido revelado

    • Há quem ache que isso acontece porque o autor é um bot
  • A afirmação de que “todas as linguagens adicionaram sum type nos últimos 20 anos, mas Ada já tinha isso desde o começo” é verdadeira, mas a origem disso não está em Ada. A linguagem Hope ou NPL vieram antes

    • Na verdade, a origem dos sum types está no artigo de 1964 de John McCarthy, “Definition of new data types in ALGOL X”. Ele propôs a palavra-chave UNION, que depois evoluiu em ALGOL 68, Hope, Miranda e outras. O union de C é diferente desse conceito
  • Gostei tanto do texto que torci para não ter sido escrito por IA, mas a velocidade das postagens no Twitter pareceu suspeita demais

    • O texto era um pouco prolixo e repetitivo, o que passava uma sensação de IA
    • Hoje em dia há muitas ferramentas de IA que fazem reescrita automática de posts de blog, então isso gera suspeita
    • Eu também gostei de ler o texto, mas só depois de ver 110 travessões pensei “será que é IA?”. É triste que até posts de blog agora precisem ser lidos com alfabetização midiática
    • Eu também escrevi 50 textos em 3 anos, mas a maioria continua inédita. Talvez esse autor tenha passado por algo parecido e só recentemente tenha criado coragem. Entendo como é frustrante ser confundido com IA
    • Se uma IA consegue escrever nesse nível, então vale a pena até se ela me tomar tempo
  • A Força Aérea dos EUA originalmente pretendia usar Ada, mas como o desenvolvimento atrasou acabou usando JOVIAL. Fiz meu primeiro projeto em JOVIAL em 1981, e naquela época Ada ainda estava na fase de especificação

    • JOVIAL era uma linguagem derivada de IAL, predecessora de ALGOL 60, e influenciou os requisitos iniciais do desenvolvimento de Ada (STRAWMAN~STEELMAN). Depois, Ada aprimorou recursos de JOVIAL e introduziu inovações como a declaração explícita de parâmetros in/out. Graças a isso, não precisou de construtores de cópia nem move semantics complexos como no C++
  • Na página principal do site há a frase “isto não é uma posição, é uma proposta”, e alguém usou isso para afirmar que o site foi escrito por IA

    • Mas essa frase não é prova de que foi escrito por IA
  • O texto dizia que “o sistema de módulos de JavaScript não consegue ocultar a representação interna de um tipo como Ada faz”, mas, na prática, em módulos JS basta não exportar para esconder bem. Fiquei em dúvida se Ada realmente tem alguma vantagem especial nisso

    • Se tomarmos TypeScript como referência, objetos JS ainda podem receber ou ter propriedades alteradas do lado de fora. Em Ada, uma instância de tipo private não pode ser manipulada fora da API definida
    • Um exemplo concreto pode ser visto neste comentário