본문으로 건너뛰기
0
r/jeffnews HN 약 4분

Quadratic Micropass Type Inference — 타입 추론 에러 메시지를 인간 사고방식에 맞추는 새로운 알고리즘

backend

요약

코드 순서가 아니라 사용자가 중요시하는 순서로 타입 추론을 수행하는 새 알고리즘 제안. 여러 마이크로패스를 우선순위 순으로 실행해서 에러 메시지가 개발자 직관에 부합하도록 함.

기사 전체 정리

Quadratic Micropass Type Inference — 타입 추론 에러 메시지를 인간 사고방식에 맞추는 새로운 알고리즘

문제: 타입 추론이 만드는 혼란스러운 에러 메시지

  • 타입 추론이 풍부한 언어들은 에러 메시지가 혼란스러운 경우가 많음. 컴파일러가 타입을 추론하는 과정에서 잘못된 가정을 먼저 하고, 그 가정에 기반한 에러를 보여주기 때문임
  • 예를 들어 fn example(x) -> Point[int]에서 xlog(["origin: ", x])에 넣고 Point(x, x)를 리턴하면, 기존 방식은 코드 순서대로 추론해서 xstring으로 먼저 잡음. 그래서 "expected int, got string" 에러가 뜨는데 — 개발자 입장에서는 xint인 게 훨씬 자연스러움. 리턴 타입이 Point[int]니까

해법: 사용자가 중요하게 여기는 순서로 타입을 추론

  • **코드 순서(top-to-bottom)**가 아니라, 사용자가 가장 중요하게 여길 법한 순서로 타입 통합(unification)을 수행하는 알고리즘을 제안함
  • 하나의 큰 추론 패스 대신 여러 개의 마이크로패스로 분리:
    1. known_applications — 함수 파라미터 타입 추론
    2. known_assignments — 할당 대상 타입 추론
    3. known_return_types — 리턴 타입 기반 추론
    4. known_same_as_unifications — 같은 리스트/분기 내 타입 통합
    5. known_record_fields — 레코드 필드 타입 추론
    6. resolve_records — 필드명으로 레코드 타입 결정
    7. less_known_functions — 호출 패턴으로 함수 타입 추론
    8. default_numbers — 숫자 리터럴 기본 타입 결정
    9. default_unknown_to_unit_or_lift — 미추론 타입 처리
  • 리스트 위쪽일수록 사용자 사고방식에 가까운 패스임. 각 패스 실행 후 이전 패스를 다시 돌려서 새로 알게 된 타입 정보가 전파되게 함

왜 "Quadratic"인가

  • 각 패스 후 이전 패스를 전부 다시 돌리니까 이론상 O(n²)임. 하지만 OCaml처럼 작은 함수가 많은 언어에서는 quadratic 특성의 심각도가 줄어듦
  • 벤치마크 (Intel i7 13700k @ 5.3GHz): 100 이터레이션에 7.79ms, 50,000 이터레이션에 2.78초. 캐시된 번역 단위 사용 시 실용적으로 충분한 성능

ℹ️참고

> 에러 생성은 추론 중이 아니라 추론 완료 후 타입 체킹 단계에서 수행됨. 각 패스는 에러를 무시하고 자기가 처리할 수 있는 타입만 건드림. 최종적으로 타입 변수 → 정적 타입 매핑을 만들어서 단순 동등 비교로 타입 체킹

  • 결과: 아까 문제의 예제에서 known_applications 패스가 먼저 돌아가면서 리턴 타입 Point[int]에서 x = int를 추론함. 그래서 에러가 **"expected string, got int"**로 바뀜 — 개발자 직관에 훨씬 부합하는 메시지

핵심 포인트

  • 기존 inside-out 추론 방식의 혼란스러운 에러 메시지 문제 해결
  • 9개 마이크로패스를 사용자 사고방식 우선순위로 정렬하여 순차 실행
  • i7 13700k에서 100 이터레이션 7.79ms 성능, 실용적으로 충분

인사이트

에러 메시지 품질은 컴파일러 UX의 핵심인데, 타입 추론 순서를 '인간이 생각하는 순서'로 바꾸는 접근이 참신함. Rust나 TypeScript처럼 추론이 복잡한 언어에 적용되면 DX가 크게 개선될 수 있음.

댓글

댓글

댓글을 불러오는 중...

backend

Redis 8.0 출시 — I/O 스레딩 갈아엎고 처리량 3배, 2.1M ops/sec 달성

Redis 8.0이 I/O 스레딩 모델을 완전히 재설계해서 16코어 기준 2.1M ops/sec를 달성함 (7.4 대비 3배). Hash field expiration, Vector search HNSW, Client-side caching v2, Redis Functions 2.0 async 실행 등 굵직한 기능이 추가되고, jemalloc 통합으로 메모리 fragmentation도 25% 줄어듦.

backend

Arm, 35년 만에 첫 자체 실리콘 제품 'AGI CPU' 발표

Arm이 35년 역사상 처음으로 자체 설계 실리콘 제품인 AGI CPU를 발표함. Neoverse V3 기반 AI 데이터센터용 프로세서로, Meta가 리드 파트너이며 랙당 x86 대비 2배 이상 성능을 주장함.

backend

Go 1.26의 타입 생성(Type Construction)과 순환 감지(Cycle Detection) 개선

Go 1.26에서 타입 체커의 타입 생성 알고리즘을 개선해 재귀 타입과 배열 크기 계산 시 발생하던 순환 감지 문제를 체계적으로 해결했다. 불완전한 값이 다운스트림으로 퍼지기 전에 업스트림에서 차단하는 새로운 접근법으로 여러 컴파일러 패닉을 수정.

backend

Cloudflare Gen 13 서버: 캐시를 코어로 바꿔 성능 2배 달성한 이야기

Cloudflare가 AMD Turin 9965(192코어) 기반 Gen 13 서버를 배포함. 코어당 L3 캐시가 6배 줄어 레거시 NGINX 스택(FL1)으로는 레이턴시 50% 악화가 불가피했으나, Rust로 전면 재작성한 FL2로 전환해 Gen 12 대비 처리량 2배, 성능/와트 50% 개선을 달성함.

backend

칩셋 레이턴시를 측정해봤더니 — 쓸모는 없지만 재밌는 실험

Vulkan GPU 벤치마크로 여러 세대 마더보드 칩셋의 PCIe 레이턴시를 측정한 실험. CPU 직결 대비 칩셋 경유 시 수백 ns 레이턴시가 추가되며, 의외로 2012년 Skylake Z170이 가장 낮은 추가 레이턴시를 보임.