Well-Typed가 GHC, Cabal, HLS 등 핵심 Haskell 툴체인 전반에서 2025년 6월부터 8월까지 수행한 작업을 정리한 28번째 Haskell 생태계 활동 보고서입니다.
이번 보고서는 Haskell 생태계 활동 보고서의 스물여덟 번째 판으로, Well-Typed가 GHC, Cabal, HLS 및 기타 핵심 Haskell 툴체인 전반에서 수행한 작업을 다룹니다. 이번 호는 대략 2025년 6월부터 8월까지의 활동을 포함합니다.
이번 호부터는 보고서명이 GHC 활동 보고서에서 변경되어, GHC 이외의 다양한 작업에 초점을 맞춘다는 점을 반영합니다. 이전 호들은 haskell-ecosystem-report 태그 아래에서 모아볼 수 있습니다.
Well-Typed는 상업적 사용자에게 전문가 지원을 제공하는 동시에, 본 보고서에 서술된 작업 등을 통해 Haskell 커뮤니티와 기술 생태계에 투자할 수 있도록 Haskell Ecosystem Support Packages를 제공합니다. 더 알아보려면 Haskell Foundation과의 파트너십으로 발표한 패키지 소개 글을 확인해 주세요. 이 필수 유지보수 작업을 계속하려면 재정적 지원이 필요합니다!
최근에는 스탠다드차타드(Standard Chartered)가 Gold Haskell Ecosystem Supporter로 참여해 주셔서 매우 기쁘게 생각합니다. 스탠다드차타드에 깊은 감사를 드리며, 다른 Haskell Ecosystem Supporter인 Channable과 QBayLogic에도 감사드립니다. 또한 이 작업이 가능하도록 기여해 주시는 기존 고객인 Anduril, Juspay, Mercury에도 감사드립니다. 마지막으로 HLS 릴리스 관리를 지원해 주신 HLS Open Collective에도 감사의 말씀을 전합니다.
현재 Well-Typed의 Haskell 툴체인 팀은 다음과 같습니다:
이 밖에도 Well-Typed 내부의 많은 분들이 가끔씩 GHC, Cabal, HLS에 기여하거나, 다른 오픈 소스 Haskell 라이브러리와 도구에 기여하고 있습니다. 이번 보고서에는 특히 Alex Washburn과 Wen Kokke의 기여가 포함되어 있습니다.
Ben은 9.14.1 릴리스를 위해 백포트를 준비하고 첫 알파 버전을 공개했습니다.
Ben과 Zubin은 GHC 9.12.3을 위한 백포트 작업을 진행했습니다.
Zubin은 9.10.3 릴리스를 준비하며 백포트를 진행하고 rc1
, rc2
, rc3
릴리스 후보를 공개했습니다.
Sam은 깊은 서브섬션(deep subsumption) 구현을 여러 가지 측면에서 개선하여, 이전에는 거부되던 프로그램을 GHC가 수용하도록 했습니다 (#26225, !14577).
Matt은 GHC의 중첩된 Template Haskell 스플라이스 처리 방식을 리팩터링하여 코드 경로를 더 일관되게 만들고 중복 코드를 제거했습니다 (!14377).
Matt은 레벨 체킹(ExplicitLevelImports
확장) 관련 버그를 수정했는데, 순환 임포트가 있을 때의 크래시 (#26087, !14478)와 누락된 레벨 검사 몇 가지를 해결했습니다 (#26088, !14479, #26090, !14550).
Andreas는 타입 클래스 특수화기가 타입 패밀리를 통과해 볼 수 있도록 하여, 특수화 기회를 더 많이 노출하게 했습니다 (#26051, !14272).
Sam은 비활성 상태여야 하는 RULES가 그럼에도 불구하고 발동할 수 있었던 상황을 찾아내고 수정했습니다 (#26323, !14687).
Ben과 Andreas는 불투명 newtype 딕셔너리 패치와 관련된 다양한 성능 문제를 조사하여, 9.14에 머지하기 위한 준비를 했습니다 (!10479).
Alex는 LLVM 백엔드에서 bitReverse
, byteSwap
, pdep
primop의 잘못된 부호 확장 및 축소를 수정했습니다 (#20645, #26109, !14609).
Alex는 LLVM 백엔드가 존재하지 않는 LLVM intrinsic llvm.x86.bmi.{pdep,pext}.{8,16}
에 대한 참조를 생성하던 문제를 고쳐, 적절한 32비트 연산 사용으로 대체했습니다 (#26065, !14647).
Andreas는 지원 범위를 벗어난 LLVM 버전을 사용할 때 오류 대신 경고를 내고 진행하도록 허용했습니다 (#25915, !14531).
Ben은 새 LLVM 버전을 지원하기 위해 내장 배열 처리 방식을 수정했습니다. 이를 통해 LLVM 백엔드에서 발생하던 다수의 테스트 실패가 해결되었습니다 (#25769, !14157).
Ben은 오랜 Windows 기여자인 Tamar Christina의 도움을 받아 Windows용 Clang 툴체인을 대폭 재작업했습니다 (!14442). 이는 API 세트 사용 등 최신 LLVM 버전의 변경 사항에 맞추기 위해 필요했습니다.
Rodrigo는 Haskell 프로그램을 위한 더 나은 디버거 도구를 향한 단계로 GHCi 디버거 개선 작업을 진행했습니다. 특히 GHCi 디버깅 시 함수에서 빠져나가기(step-out)를 지원하는 새로운 :stepout
명령을 구현했습니다 (#26042, !14416). 또한 대규모 프로그램을 GHCi로 로드할 때 카운터가 오버플로우될 수 있어 중단점 인덱스를 16비트에서 32비트로 확장했고 (#26325, !14691), 그 밖의 여러 중단점 관련 개선도 수행했습니다 (!14461, !14480, !14534).
Andreas는 바이트코드 인터프리터에서 엔디언과 관련된 문제를 수정했는데, 일부 플랫폼에서 원시 연산 결과가 잘못 나오는 원인이 되었습니다 (#25791, #23387, !14172).
Hannes는 새로운 GHCi 플래그 -fno-load-initial-targets
를 추가하여, 시작 시 모든 타깃 모듈을 즉시 로드하지 않고도 GHCi를 기동할 수 있게 했습니다. 사용자는 :reload
로 관심 있는 모듈만 선택적으로 로드할 수 있습니다 (#26144, !14448). 대규모 프로젝트의 일부만 작업할 때 GHCi 시작 시간을 크게 줄일 수 있습니다.
Hannes는 GHCi의 :reload
명령과 다중 홈 유닛의 상호작용에서 남아 있던 문제들을 수정했습니다 (#26128, !14427).
Matt은 인터프리터 통계 계산의 버그 일부를 수정했습니다 (#25756, !13956, #25695, !13879).
Wen은 이벤트로그 비용 센터와 샘플 레이블 문서, 그리고 힙 프로파일 ID 문서를 개선했습니다 (!14499, !14506).
Andreas는 -fexpose-overloaded-unfolding
, -fdo-clever-arg-eta-expansion
GHC 플래그에 @since
주석을 추가했습니다 (#26112, #26113, !14517).
Andreas는 링커에 COFF``BigObj
파일 지원을 추가했습니다 (!14582).
Ben은 아카이브 멤버를 식별할 때 파일 확장자에 대한 링커의 의존도를 낮췄습니다 (#13103, #24230, !14405).
Hannes는 호출 스택에 임의의 데이터를 주석으로 달 수 있도록 하는 새로운 primop와 ghc-experimental
API를 추가하여, 더 나은 백트레이스를 위한 토대를 마련했습니다 (#26218, !14538). 자세한 내용은 최근 블로그 글 Better Haskell stack traces via user annotations를 참고하세요.
Hannes는 Backtraces
타입의 구현을 개선하고, 백트레이스 메커니즘이 스택 디코더를 구성할 수 있도록 확장했습니다 (#26211, !14532). 또한 Backtraces
타입의 내부 구현을 base
에서 노출하려던 변경을 되돌렸는데, 이는 CLC 제안이 필요하기 때문입니다 (!14587).
Andreas는 조인 포인트에 대해 -fprof-late-overloaded-calls
기능을 비활성화했는데, 이로 인해 GHC가 크래시할 수 있었기 때문입니다 (#26138, !14460). 이는 근본 원인을 완전히 해결하기 전까지의 임시 조치입니다.
Matt은 프로파일링용 정보 테이블 엔트리를 분리 배치할 수 있도록 허용했습니다 (#21766, !14465).
Wen은 비스레드 RTS에서 --eventlog-flush-interval
사용을 비활성화하여 이벤트로그 손상을 방지했습니다 (#26222, !14547).
Wen은 이벤트로그 트레이스에서 사용되지 않는 하드코딩된 profile_id
를 제거했습니다 (!14507).
Ben은 생성자 ctoi
튜플 정보 테이블을 재사용할 수 있도록 데이터 섹션으로 분리했습니다 (!14508).
Ben은 정보 테이블 출처(provenance) 테이블에 대한 zstd
압축 지원의 회귀를 수정했습니다 (#26312).
ghc
라이브러리initNameCache
의 대체로, 오용 가능성이 낮은 newNameCache
를 추가했습니다 (!14446).이는 weeder
라이브러리가 initNameCache
를 잘못 사용하던 버그에 대한 대응이었습니다 (weeder
#194, #26055).
Rodrigo는 base
에 displayExceptionWithInfo
를 내보내도록 추가하여 CLC 제안 #344를 구현했습니다 (!14419).
Hannes는 CLC 제안 #212를 구현하여 GHC.Exts
에서 더는 필요하지 않은 힙 표현 세부 사항 일부를 제거했습니다 (!14544).
Ben은 내부 자료형 IOPort
를 제거하고 MVar
로 대체하여 CLC 제안 #213을 구현했습니다 (!8776).
Zubin은 바이너리 배포판에 사용자 가이드 PDF가 포함되지 않던 문제를 수정했습니다 (#24093, !14469).
Ben은 ghc-toolchain
에 otool
, install-name-tool
, llc
, opt
등의 LLVM 유틸리티 지원을 추가했습니다 (#23675, !14050).
Ben은 CrossCompiling
프레디킷을 오버라이드할 수 있도록 했습니다 (#26236, !14568).
Ben은 더 이상 권장되지 않는 ld.gold
링커를 선호하던 빌드 시스템 로직을 제거했습니다 (#25716, !14324).
Hannes와 Zubin은 MacOS (!14601), Windows (!14622), FreeBSD (!14666)에서 부트스트랩 컴파일러를 9.10.1로 업그레이드했습니다. 이를 바탕으로 Hannes는 test-bootstrap
잡을 9.10.1을 사용하도록 업데이트했습니다 (!14676).
Zubin은 테스트 제품군 드라이버가 특정한 허위(스푸리어스) 링커 경고를 더 잘 걸러내도록 개선했습니다 (#26249, !14615).
Matt은 Cabal 프로젝트가 공식 제안 절차를 도입하도록 돕기 위해 Cabal Proposals Process 문서를 작성했습니다. 이 문서는 Cabal #11006에서 논의되었고 기존 Cabal 메인테이너들에 의해 최종 승인되었습니다.
Matt은 바이트코드 산출물 지원을 추가하는 Cabal 제안을 열었는데, 이는 GHCi 사용을 가속화하고 base
같은 의존성 코드를 포함하여 GHCi 디버거가 의존성을 단계별로 추적할 수 있게 합니다 (Cabal Proposals #2).
Matt은 기여자 Julian G (@jgotoh)이 진행하던 cabal.project
파서의 Parsec
마이그레이션 작업을 마무리하는 데 도움을 주었습니다 (Cabal #8889).
Matt은 CI 릴리스 스크립트를 업데이트하여 부트 컴파일러 버전을 올리고 플랫폼을 갱신했습니다 (Cabal #11032).
Matt은 base-4.21
에서의 예외 컨텍스트 변경에 Cabal 라이브러리가 적응하도록 수정했습니다 (Cabal #11125). 이 이슈는 Cabal #10684에서 Phil de Joux의 미스터리한 문제를 조사하던 중에 드러났습니다.
Matt은 멀티 REPL 세션을 시작할 때 긴 커맨드라인 인자를 넘기는 대신 응답 파일(response file)을 사용하도록 변경했습니다 (Cabal #10995). 다만 출시된 HLS 바이너리 배포판과의 호환성을 유지하기 위해 Cabal 3.16 릴리스에서는 이 변경을 되돌렸습니다 (Cabal #11101). 계획은 HLS가 적응할 시간을 주기 위해 Cabal 3.18에서 응답 파일 사용을 다시 진행하는 것입니다.
Matt은 Hannes의 도움을 받아 cabal-install repl
명령에 --with-repl
플래그를 추가하여, hie-bios
와 doctest
같은 외부 도구가 GHCi 세션을 시작하는 데 필요한 옵션을 쉽게 알아낼 수 있도록 했습니다 (Cabal #10996).
hie-bios
가 세션 로드에 Cabal의 --with-repl
명령을 사용하도록 만들어, 구현과 다중 홈 유닛 처리의 복잡성을 크게 줄였습니다 (hie-bios
#466).Hannes는 스택 클로저에 대해 IPE 정보를 인라인으로 표시하도록 했습니다 (ghc-debug
#73).
Matthew는 쿼리가 실행되는 동안에도 ghc-debug-brick
터미널 인터페이스를 점진적으로 업데이트할 수 있도록 했습니다 (ghc-debug
#68).
Hannes는 ghc-debug-brick
모듈 계층 구조를 재구성했고 (ghc-debug
#72), 이를 별도의 라이브러리로 제공하도록 했습니다 (ghc-debug
#74).
Hannes는 사용자 지정 스택 주석을 지원하도록 추가했습니다 (ghc-debug
#69).
Ben은 haskell.org
의 메일 전송 및 메일링 리스트 인프라를 더 관리하기 쉬운 호스팅 환경으로 마이그레이션했습니다. 여기에는 NixOS에서 메일 전송 구성을 재구축하고, 20년에 걸친 메일링 리스트 데이터를 mailman-2
에서 mailman-3
로 이전하며, 기존 mailman-2
아카이브의 가용성을 보장하는 방식을 구현하는 작업이 포함되었습니다.
사용자 피드백에 대응하여, Ben은 더 다양한 패키지를 빌드할 수 있도록 Hackage 문서 빌더를 여러 측면에서 개선했습니다.
Ben은 Haskell Foundation과 협력하여 Azure 오픈 소스 프로그램 종료로 인해 줄어든 용량을 대체할 AArch64/Linux용 신규 CI 러너 세트를 준비했습니다.
ghc-typelits-natnormalise
라이브러리를 ghc-tcplugin-api
를 사용하도록 마이그레이션했습니다 (ghc-typelits-natnormalise
#90).이를 통해 ghc-typelits-natnormalise
가 다양한 GHC 버전에서 동작하도록 유지하는 부담이 줄어들었습니다. 이 과정에서 기존의 버그 몇 가지도 함께 수정되었습니다 (ghc-typelits-natnormalise
#47, ghc-typelits-natnormalise
#70, ghc-typelits-natnormalise
#71).
eventlog-socket
라이브러리를 개선하여, C에서 이벤트로그 기록자를 설정할 수 있도록 하고, 사용 예제를 문서화했습니다.