ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SE-0521] Improved Syntax for Optionals of Opaque and Existential Types
    Swift 2026. 5. 1. 06:51

    안녕하세요. 그린입니다 🍏

    이번 포스팅에서는 SE-0521 — Opaque 및 Existential 타입의 Optional 문법 개선에 대해 정리해보겠습니다 🙋🏻


    Intro

    • Proposal: SE-0521
    • Author: Tony Allevato
    • Review Manager: Frederick Kellison-Linn
    • Status: Accepted with modifications

    Motivation

    Swift에서 some Pany P는 이미 익숙한 문법이죠.

    개발자들은 자연스럽게 Int?, String?처럼 some P? 또는 any P?라고 쓰고 싶어 합니다.

    그런데 현재 이 코드는 컴파일 에러가 발생합니다 🐛

    func fetchUser() -> some Identifiable?  // ❌ error
    var handler: (any EventHandler)?        // ✅ 이렇게 써야 함
    var handler: any EventHandler?          // ❌ error

    이유는 파싱 우선순위 때문입니다.

    컴파일러는 some P?some (P?)로 해석하는데, Optional<P>는 프로토콜이 아니기 때문에 에러가 발생하게 됩니다.

    결국 개발자들은 어쩔 수 없이 (some P)?, (any P)?처럼 괄호를 추가해서 써야 했어요.

    커뮤니티에서도 "ExistentialAny를 적용하고 나서 괄호 때문에 가독성이 너무 떨어진다"는 불만이 꽤 많았던 주제였거든요!

    Detailed Design

    이번 제안의 핵심은 간단합니다.

    some P?any P?를 각각 (some P)?, (any P)?동일한 의미로 허용하는 것입니다.

    기본 동작

    some P?  // == (some P)?  ✅
    any P?   // == (any P)?   ✅
    any P!   // == (any P)!   ✅

    다중 Optional도 지원

    var a: some P??  // == (some P)??
    var b: any P???  // == (any P)???

    파서는 변경 없음

    some P?는 여전히 OpaqueResultTypeRepr(OptionalTypeRepr(P))의 형태로 파싱되며, TypeRepr(AST) 자체도 바뀌지 않습니다. 단지 타입 체커가 이 구조를 만났을 때 의미를 재해석하는 방식만 바뀌는 것입니다.

    함수 파라미터에서도 동작

    func process(_ item: some Identifiable?) { }
    // == func process<T: Identifiable>(_ item: T?) { }

    Fix-it도 개선

    // Before fix-it
    let x: P?
    // warning: ... fix-it → (any P)
    
    // After fix-it
    let x: P?
    // warning: ... fix-it → any P  (괄호 없음!)

    주의: 프로토콜 컴포지션은 여전히 괄호 필요

    // ❌ 여전히 에러: P & Q? 자체가 invalid
    var x: some P & Q?
    
    // ✅ 이렇게 써야 합니다
    var x: (some P & Q)?
    
    // ✅ typealias 활용도 가능
    typealias PQ = P & Q
    var x: some PQ?  // OK!

    Accepted with modifications

    Language Steering Group은 원 제안에 수정 사항을 추가해 승인했습니다.

    바로 suppressed constraints(~)에도 동일한 개선을 적용하는 것입니다.

    any ~Copyable?   // == (any ~Copyable)?  ✅
    some ~Copyable?  // == (some ~Copyable)? ✅
    
    var x: ~Copyable?  // ⚠️ warning: requires 'any'

    단, .swiftinterface 파일에는 기존처럼 괄호를 포함한 형태((any P)?)가 유지됩니다.

    해당 파일은 컴파일러가 소비하는 아티팩트이지, 개발자가 직접 읽는 용도가 아니기 때문이에요.


    Source Compatibility / ABI

    • 이번 변경은 순수 additive 변경으로, 기존 코드와의 소스 호환성은 100% 유지됩니다.
    • 기존의 (some P)? 형태는 여전히 유효합니다.
    • some/any P?(some/any P)?의 타입 맹글링은 동일하므로 ABI에도 영향이 없습니다.

    Alternatives Considered

    아무것도 하지 않기

    괄호 방식을 그대로 유지하는 것도 방법이지만, ExistentialAny가 언젠가 필수가 된다면 코드베이스 전반에 걸쳐 괄호가 대량으로 생겨나는 문제가 있거든요.

    제안자는 이를 미리 해결하는 것이 적절하다고 판단했습니다.


    Conclusion

    작은 변경이지만, any/some 타입을 자주 쓰는 코드베이스에서는 가독성이 꽤 많이 개선되는 실용적인 변경입니다 🙌

    Int?를 쓰듯이 any Protocol?, some Protocol?을 자연스럽게 쓸 수 있게 되면서, Swift의 타입 시스템이 한층 일관적이고 직관적으로 느껴지게 될 것 같습니다!

    특히 ExistentialAny를 이미 적용한 프로젝트에서는 산더미 같은 괄호들을 제거할 수 있겠네요 😄


    References

     

    swift-evolution/proposals/0521-improved-optional-opaque-and-any.md at main · swiftlang/swift-evolution

    This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution

    github.com

Designed by Tistory.