Ada, 그 설계와 언어를 만든 언어
(iqiipi.com)- 1970년대 미국 국방부의 소프트웨어 혼란 속에서 탄생한 Ada는 강한 정적 타입과 명세-구현 분리를 핵심으로 한 언어임
- 패키지 구조와 표현적 은닉을 통해 완전한 캡슐화를 구현하며, 이후 Java·C#·Go 등 현대 언어의 모듈 시스템에 영향을 줌
- 의미적 제약 타입, 제네릭, 동시성(task), 계약 기반 설계 등은 Ada가 수십 년 앞서 제시한 개념으로, Haskell·Rust·Swift 등이 이를 계승함
- SPARK Ada는 정형 검증을 통해 데이터 경합과 논리 오류까지 제거하며, 항공·철도·방위 시스템 등 고신뢰 분야에서 사용됨
- Ada는 대중적 언어는 아니지만, “조용히 올바르게 작동하는 언어” 로서 현대 프로그래밍 언어 설계의 근본 원칙을 제시한 기반임
Ada의 탄생 배경과 설계 철학
- 1970년대 초 미국 국방부(DoD) 는 무기·물류·통신 시스템에 450개 이상의 언어와 방언이 혼재된 상황을 조사함
- 각 시스템은 상호 운용 불가, 유지보수 불가능, 원 저자 부재 등의 문제를 가짐
- 이로 인해 소프트웨어 조달 위기가 발생
- DoD는 기존 언어(COBOL, Fortran, PL/1 등)를 채택하지 않고, 5년간의 요구사항 정의 과정을 거침
- Strawman → Woodenman → Tinman → Ironman → Steelman 문서로 발전
- Steelman(1978)은 명시적 인터페이스 분리, 강한 정적 타입, 내장 동시성, 일관된 예외 처리, 기계 독립성, 가독성, 검증 가능성을 요구
- 1979년 4개 팀(Green, Red, Blue, Yellow) 간 경쟁에서 Jean Ichbiah가 이끄는 Green 팀이 선정되어 Ada로 명명됨
- 이름은 Ada Lovelace를 기려 붙여졌으며, 언어의 의도를 상징
패키지 구조와 캡슐화
- Ada의 중심 구조는 패키지(package) 로, 명세(specification)와 본체(body)가 물리적으로 분리됨
- 명세는 외부에 공개되는 계약, 본체는 구현이며, 컴파일러가 두 관계를 강제
- 클라이언트 코드는 명세에 없는 요소에 접근 불가
- 이 구조는 모듈 시스템의 원형으로, 이후 언어들이 이를 부분적으로 모방
- Java, Python, JavaScript, C, Go, Rust 모두 Ada의 완전한 구조적 분리를 구현하지 못함
- private 타입은 이름만 노출되고 내부 표현은 완전히 불투명함
- 클라이언트는 타입의 내부 구조를 알 수 없으며, 허용된 연산만 사용 가능
- 이는 Java의
private접근제어보다 강력한 표현적 은닉(representational invisibility)
- Java와 C#은 수십 년에 걸쳐 점진적으로 Ada 수준의 캡슐화를 향해 발전
타입 시스템과 의미적 제약
- Ada는 타입과 서브타입의 구분을 수학적 의미로 정의
- 예:
type Age is range 0 .. 150은 범위 제약을 가진 별도 타입 생성 - 잘못된 타입 간 전달은 컴파일 타임 오류로 검출
- 예:
- 1983년 당시 Ada의 타입 시스템은 C, Fortran, Pascal보다 훨씬 표현력이 높았음
- 의미적 제약 타입을 통해 도메인 오류를 방지
- 판별 레코드(discriminated record) 는 값에 따라 다른 필드를 갖는 구조
- 이는 현대 언어의 합타입(sum type) 또는 대수적 데이터 타입(ADT) 과 동일
- Haskell, Rust, Swift, Kotlin, TypeScript 등이 수십 년 후 동일 개념을 도입
제네릭과 다형성
- Ada의 제네릭(generic) 은 타입·값·서브프로그램·패키지를 매개변수로 받는 단위
- 컴파일 시 타입 검증을 수행하는 정적 다형성(parametric polymorphism) 구현
- C++(1990), Java(2004), C#(2005), Go(2022) 등은 Ada 이후 수십 년에 걸쳐 유사 기능을 도입
- Java는 타입 소거(type erasure) 로 런타임 타입 정보 손실
- Ada는 런타임 타입 보존 및 패키지 매개변수화까지 지원
- Ada의 제네릭은 고차 다형성(higher-kinded polymorphism) 수준의 표현력 제공
- Haskell의 타입 클래스, Rust의 트레이트, C++20의 concepts와 유사한 개념
동시성 모델과 안전성
- Ada는 1983년부터 언어 수준의 동시성(task) 을 내장
task선언과 rendezvous 통신 모델을 통해 공유 상태 없는 메시지 전달 구현- Go의 channel은 동일한 CSP(Communicating Sequential Processes) 계열의 개념
- Ada 95는 protected object를 도입
- 데이터 접근을 보호하며,
procedure,function,entry로 구분 - 자동 배리어 조건과 락 없는 동기화 제공
- 데이터 접근을 보호하며,
- SPARK Ada는 정형 검증을 통해 데이터 경합, 예외, 범위 오류, 사전·사후조건 위반이 없음을 수학적으로 증명
- Rust의 borrow checker는 메모리 안전성만 보장하는 반면, SPARK는 논리적 정합성까지 증명
계약 기반 설계와 null 안전성
- Ada 2012는 계약(contracts) 을 언어에 통합
- 전제조건(precondition), 사후조건(postcondition), 타입 불변식(invariant) 을 명시
- SPARK 도구 체인은 이를 정적 증명에 활용
- Eiffel(1986)의 Design by Contract 개념을 언어 차원에서 정식화
- C++, Java, Python, Rust 등은 부분적 또는 라이브러리 수준 구현에 머무름
- Ada 2005는
not null타입을 도입해 컴파일 타임 null 배제 지원- 기본은 런타임 예외(
Constraint_Error) 발생으로 안전한 실패 보장 - C# 8.0의 nullable reference와 유사한 접근
- 기본은 런타임 예외(
예외 처리 구조
- Ada 83은 최초로 구조적 예외 처리(structured exception handling) 를 도입
- 예외는 선언 후 사용, 스코프 단위로 처리, 전파 규칙 명확
- Java의 checked exception은 Ada보다 발전된 형태로, 호출자가 예외를 명시해야 함
- Ada는 예외 전파를 자유롭게 허용
- Rust는 예외를 제거하고
Result타입 기반 오류 처리를 채택- Ada의 기여는 예외 전파를 구조화하고 예측 가능하게 만든 점
Annex와 표준화 구조
- Ada 표준은 Annex라는 선택적 확장 구조를 가짐
- Annex C~H는 시스템, 실시간, 분산, 수치, 고신뢰 분야별 기능 정의
- 컴파일러는 Annex별 독립 인증을 받아야 함
- ACAA의 ACATS 테스트를 통해 표준 적합성 검증
- DO-178C 항공 소프트웨어 인증에 Ada의 표준 구조가 직접 활용 가능
- C/C++도 동일 인증 가능하지만, Ada는 구조적으로 더 적합
Ada의 영향과 인식의 불균형
- Ada는 정부 주도 언어로, 실리콘밸리 문화권에서 주목받지 못함
- C 기반의 간결한 문법 선호 문화와 대비
- Ada의 성공 사례(항공, 철도, 방위 시스템)는 실패가 없기에 가시성이 낮음
- 신뢰성 높은 시스템은 논의나 사건을 생성하지 않음
- 현대 언어의 발전 방향은 Ada가 이미 제시한 원칙으로 수렴
- 명세-구현 분리, 정적 타입 검증, 언어 수준 동시성, 계약 기반 안전성 등
- Ada는 여전히 항공기, 철도, 우주선 등 고신뢰 시스템에서 운용 중이며, “조용히 올바르게 작동하는 언어” 로 남아 있음
Hacker News 의견들
-
나는 Ada를 좋아함. 그런데 타입 처리 얘기하면서 ML 계열 언어(ML, SML, CML, Caml, OCaml 등)를 완전히 빼놓은 게 놀라움
이 언어들은 구조적 타입을 컴파일러 수준에서 지원함. Ada는 PL/I, PHP, Perl처럼 언어 자체가 너무 크고 문법이 복잡한 게 문제였음. 글에서는 그게 장점이라고 하지만, 개인적으로는 Annex로 분리된 표준 확장이 더 훌륭했다고 봄. 만약 핵심 언어를 작게 하고 Annex 중심으로 갔다면 더 널리 쓰였을 것 같음- ML 언어에서는 사용자가 직접 bounded Integer/Floating point 타입을 정의할 수 없음. Ada의 핵심 기능 중 하나가 바로 이런 타입 시스템임. Ada의 타입 시스템을 경험해보면 코드 품질과 신뢰성이 얼마나 높아지는지 놀라게 됨
-
Ada가 외면받은 이유 중 하나는 컴파일러 가격이 수만 달러였기 때문임. 무료나 오픈소스 컴파일러가 없던 시절, 다른 언어들은 공짜로 쓸 수 있었음. 그게 결정적 요인이었음
- Ada가 틈새를 벗어나지 못한 이유는 여러 가지가 겹쳤음. 언어의 복잡성과 당시 컴파일러 기술로는 1980년대 마이크로컴퓨터에서 제대로 돌릴 수 없었음. Intel이 Ada 개념을 하드웨어에 녹인 i432를 만들었지만 성능이 형편없었음. 이후 마이크로컴퓨터가 세상을 장악하면서 C와 어셈블리 유산이 20년 넘게 이어졌음
- 나는 Ada를 몇 년 썼는데, 동료들이 취미로 다른 언어를 쓰는 게 Ada 확산에 도움이 안 됐음. 문자열 처리도 약했고, 속도도 느렸음. 특히 동시성 처리가 OS 스레드를 안 써서 불편했음. 결국 HPUX의 실시간 확장을 써서 여러 프로세스로 돌렸음
- 90년대 중반부터 GNAT이 있었고, 그 시절엔 상용 컴파일러도 흔했음. Ada가 막힌 이유는 ‘불필요한 오버헤드’라는 인식 때문이었음. 즉, 군용이나 안전 시스템 외에는 쓸 이유가 없다는 평판이 있었음
- GNU Ada Compiler(GNAT)는 1995년에 처음 공개됨
- 사실 80년대엔 어떤 언어든 컴파일러 품질이 별로였음. GCC도 후반부 들어서야 쓸 만했음. 새 언어를 쓰면 컴파일러가 미숙한 건 당연했음. C++도 당시엔 Ada보다 한참 뒤처졌고, ‘C++의 킬러 기능’은 사실상 C처럼 쓸 수 있었다는 점이었음. Ada가 Pascal 호환 모드를 제공했더라면 역사가 달라졌을지도 모름
-
글을 읽으며 Ada와 글 자체 모두 흥미로웠지만, 몇몇 사실 오류가 눈에 띄었음. 예를 들어 Ada만이 구현과 명세를 완전히 분리한다고 했는데, JavaScript도 ES6 모듈에서 private 요소를 정의할 수 있음. Java의
private가시성 설명도 틀렸음. 이런 오류들 때문에 글의 신뢰도가 떨어짐- Ada에서는
private타입을 정의하면 외부에서 내부 필드에 접근할 수 없음. 반면 JavaScript에서는 어떤 객체든 자유롭게 속성을 추가·삭제할 수 있음. 즉, Ada의 컴파일 타임 보호 수준은 JS와 비교 불가임 - Java에서는 reflection으로 private 멤버에 접근 가능함.
setAccessible(true)로 String 내부를 수정할 수도 있음 - LLM이 인간 독자를 대상으로 글을 쓸 때 Gell-Mann amnesia처럼 작동한다는 말이 인상적이었음
- Ada에서는
-
글 전반은 좋았지만, 계속 반복되는 “언어 X는 이 기능이 Ada보다 늦게 생겼다”는 문장이 지루했음. 코드 예시가 있었다면 훨씬 설득력 있었을 것 같음
- 사실 Ada의 많은 기능은 기존 언어들(PASCAL, CLU, MODULA, CSP 등)에서 차용한 것이었음. 완전히 새로운 개념이라기보다 검증된 아이디어를 통합한 결과였음
- Ada가 먼저 도입했다고 주장하는 개념 중 일부는 실제로는 다르게 구현된 경우가 많음. 그래서 비교 예시가 필요했음
- 이 글은 “Ada가 최고”라는 주장이 아니라, Ada가 안전성과 신뢰성을 위해 어떤 설계를 했는지를 보여주는 글임. 연도 비교는 그 맥락에서 의미가 있음
- 나는 Claude에게 Ada 데모 코드를 요청해봤는데 꽤 괜찮았음. Ada를 오래 알고 있었지만 직접 써보니 FOMO가 느껴졌음
- Ada 개발자 입장에서는 이런 비교 패턴이 오랜 세월 반복돼서 피로하게 느껴질 수도 있음
-
이 트위터 계정은 2026년 4월에 만들어졌고, 저자가 명시되어 있지 않음. 짧은 기간에 엄청난 생산성을 보였는데, 이름을 드러내지 않은 점이 흥미로움
- 저자가 없는 이유는 봇이기 때문이라는 의견도 있음
-
“모든 언어가 지난 20년간 sum type을 추가했지만 Ada는 처음부터 있었다”는 주장은 사실이지만, 그 기원이 Ada는 아님. Hope 언어나 NPL이 먼저였음
- 실제로 sum type의 기원은 1964년 John McCarthy의 “Definition of new data types in ALGOL X” 논문임. 그는
UNION키워드를 제안했고, 이후 ALGOL 68과 Hope, Miranda 등에서 발전했음. C의union은 이 개념과 다름
- 실제로 sum type의 기원은 1964년 John McCarthy의 “Definition of new data types in ALGOL X” 논문임. 그는
-
글이 너무 마음에 들어서 AI가 쓴 게 아니길 바랐지만, 트위터 게시 속도가 너무 빨라서 의심스러웠음
- 글이 약간 장황하고 반복적이라 AI 느낌이 났음
- 요즘엔 블로그 글을 자동으로 리라이트하는 AI 도구가 많아서 의심이 생김
- 나도 글을 즐겁게 읽었지만, 110개의 em dash를 보고 나서야 “혹시 AI?”라는 생각이 들었음. 이제 블로그 글조차 미디어 리터러시로 읽게 되는 게 슬픔
- 나도 3년간 50개 글을 썼지만 대부분 미발행 상태임. 혹시 이 저자도 비슷한 상황이었다가 최근에 용기를 낸 걸 수도 있음. AI로 오해받는 게 얼마나 좌절스러운 일인지 이해함
- 만약 AI가 이런 수준의 글을 쓸 수 있다면, 시간을 빼앗겨도 좋을 만큼 가치 있음
-
미 공군은 원래 Ada를 쓰려 했지만 개발이 늦어져 JOVIAL을 사용했음. 나는 1981년에 JOVIAL로 첫 프로젝트를 했고, 그때 Ada는 아직 명세 단계였음
- JOVIAL은 ALGOL 60의 전신인 IAL에서 파생된 언어로, Ada 개발 초기 요구사항(STRAWMAN~STEELMAN)에 영향을 줬음. 이후 Ada는 JOVIAL의 기능을 개선해 in/out 파라미터 명시 같은 혁신을 도입했음. 이 덕분에 C++처럼 복잡한 복사 생성자나 move semantics가 필요 없었음
-
사이트 메인에 “이건 입장이 아니라 제안이다”라는 문구가 있는데, 그걸 근거로 AI가 쓴 사이트라고 주장함
- 하지만 그 문장이 AI 작성의 증거는 아님
-
글에서 “JavaScript의 모듈 시스템은 Ada처럼 타입의 내부 표현을 숨기지 못한다”고 했는데, 사실 JS 모듈에서 export하지 않으면 충분히 숨길 수 있음. Ada가 특별히 더 나은 점이 있는지 의문이었음
- TypeScript를 기준으로 보면, JS 객체는 여전히 외부에서 속성을 추가하거나 수정할 수 있음. Ada에서는 private 타입 인스턴스에 대해 정의된 API 외의 조작이 불가능함
- 구체적인 예시는 이 댓글을 참고할 수 있음