스폰서LobeHubLobeHub자세히 알아보기
dshfind

13과: 토론, 관련 연구, 그리고 정리

한 문장 요약: 논문은 형식 모델과 구현을 설명한 뒤 세 가지 마무리 작업을 합니다——제5장 「토론」은 패러다임을 실제 엔지니어링으로 밀어 나가고(서비스 프록시, 샌드박스, 언어 독립성, 컴포넌트 세분성, 버전 관리), 제6장 「관련 연구」는 이를 학술 지도 위에 올려놓고 Effekt, AOP, DSU 같은 이웃 연구들과 하나하나 경계를 그으며, 제7장 「결론」은 「두 개의 차원, 하나의 구현, 하나의 미래」로 전체를 마무리합니다——이번 과를 다 읽으면 Cordis 논문 전체를 다 읽은 것입니다.

1. 엔지니어링 확장: 「동작하는 것」에서 「쓰기 좋은 것」으로

앞의 과들에서는 패러다임이 성립함을 증명했습니다(제3장 형식 모델 + 제4장 Cordis 구현). 제5장은 여기서 한 걸음 더 나아갑니다. 이 패러다임은 실제 엔지니어링에서 어떻게 쓰이고, 어떤 문제를 만날까요? 다섯 가지 주제를 하나씩 살펴겠습니다.

1.1 서비스 멀티플렉싱: 하나의 인터페이스, 여러 개의 구현

컴포넌트 플랫폼(예: OSGi)은 「서비스」를 조합의 기본 단위로 봅니다. 프로바이더가 어떤 인터페이스로 서비스를 게시하고 컨슈머가 그것에 바인딩합니다. Cordis에서 서비스란 「어떤 키 뒤에 있는 인터페이스」입니다. 같은 인터페이스에 여러 구현이 있는 경우가 흔한데, 어떻게 관리할까요? 두 가지 방식이 있습니다.

독점 바인딩서비스 프록시
메커니즘임의의 시점에 최대 하나의 구현만 바인딩. 전환 시에는 기존 프로바이더를 먼저 언로드한 뒤 새 프로바이더를 로드함중앙 「프록시」 서비스가 인터페이스의 진입점이 되고, 여러 프로바이더가 공존하며, 프록시가 각 요청을 디스패치함
전환 시전환할 때마다 컨슈머의 의존성을 교란하여 리로드를 트리거함프록시는 제자리에 남아 있어 백엔드 프로바이더를 업데이트하더라도 컨슈머는 전혀 인지하지 못하고 리로드도 트리거되지 않음
비유스턴트 대역이 한 명뿐이라 바꾸려면 공연 전체를 멈춰야 함소속사가 여러 스턴트 대역을 두고 있어 사람을 바꿔도 관객은 알아채지 못함

프록시는 왜 교란을 흡수할 수 있을까요? 컨슈머가 의존하는 것은 「프록시」라는 고정된 진입점 하나뿐이기 때문입니다. 백엔드가 바뀌어도 진입점은 변하지 않으므로 의존성도 자연히 변하지 않습니다. 이 작은 설계가 세 가지 인프라 수준의 능력을 직접 떠받칩니다.

  1. 로드 밸런싱——여러 프로바이더가 공존하고, 프록시가 라운드 로빈, 최소 부하, 지연 가중치 등의 전략으로 요청을 디스패치합니다. 스케일 아웃/인을 하려면 프로바이더를 추가하거나 제거하면 됩니다. 주의: 각 프로바이더는 가역 이펙트를 통해 프록시에 등록되므로, 언로드되면 등록이 자동으로 취소되어 프록시의 라우팅 테이블에서 자동으로 한 항목이 줄어들고, 더러운 데이터가 남지 않습니다.
  2. 롤링 업데이트——런타임에 서비스를 업그레이드하는 것은 통제된 「프로바이더 마이그레이션」입니다. 먼저 새 프로바이더를 로드해 프록시에 등록하고, Active 상태에 들어가기를 기다린 다음, 트래픽을 기존 프로바이더에서 점진적으로 새 프로바이더로 옮깁니다(예: 가중치 조정). 기존 프로바이더가 진행 중인 요청을 더 이상 담당하지 않게 된 후에 언로드합니다. 이는 「블루-그린 배포」나 「컨테이너 오케스트레이션」 같은 인프라 계층의 일을 애플리케이션 계층의 조합 패턴으로 바꾸는 것과 같습니다.
  3. 프로세스 간 호출——프록시는 프로세스를 넘나들며 작동할 수도 있습니다. 각 프로세스는 자체 Cordis 컨텍스트와 로컬 프로바이더를 가지며, 조정 컴포넌트가 이들을 연결하여 각 프로세스를 원격 프로바이더로 취급합니다. 분산은 컨슈머에게 투명합니다. ⚠️ 하지만 프로세스 간 호출에는 지연이 있고 도중에 실패할 수 있으므로, 인터페이스는 비동기 계약에 따라 설계해야 합니다. 그렇지 않으면 동기 호출이 호출자를 블록합니다.

1.2 접근 제어와 샌드박스: 로드할 수 있어야 하지만, 통제할 수도 있어야 한다

독립적인 컴포넌트로 조립된 애플리케이션은 보안을 두 갈래로 챙겨야 합니다. ① 컴포넌트가 어떤 의존성에 접근할 수 있는지를 제한한다. ② 신뢰할 수 없는 코드를 호스트 환경으로부터 격리한다.

첫 번째: 의존성 선언이 곧 케이퍼빌리티 요청이다. 기억하시나요? 컴포넌트는 자신이 「선언한」 의존성에만 접근할 수 있고, 선언하지 않은 것에 접근하면 오류가 발생합니다. 이것은 구조적으로 「케이퍼빌리티 기반 보안」(capability-based security)입니다. 권한은 참조를 보유하는 데서 나오지, 「이 환경의 구성원이라는 사실」에서 나오지 않습니다. inject 선언 = 케이퍼빌리티 요청, 컨텍스트 프록시 = 케이퍼빌리티 중개자입니다. 게다가 이 요청들은 정적으로 선언되어 있으므로, 오케스트레이터는 로드 시점에 검토하고 승인할 수 있으며, 접근이 실제로 일어난 뒤에야 하나씩 위반을 발견할 필요가 없습니다.

인터셉션으로 세밀한 정책을 만들 수 있다. 컨텍스트는 접근 제어 메타데이터를 가질 수 있고, 프로바이더는 호출할 때마다 메타데이터를 참조해 허용 여부를 결정합니다(예: 파일시스템 의존성은 「이 컴포넌트가 어떤 경로를 읽고 쓸 수 있는지」에 대한 메타데이터를 가짐). 핵심은 인터셉션이 컨텍스트에 걸려 있고 어느 쪽 코드에도 상주하지 않는다는 점입니다——따라서 오케스트레이터는 어떤 프로바이더 코드도 변경하지 않고 특정 컴포넌트만 따로 제약할 수 있습니다(예: 커뮤니티 컴포넌트는 데이터베이스에 읽기 전용으로 접근, 코어 컴포넌트는 전체 접근). 또한 인터셉션은 「호출 방식」에만 영향을 주고 「의존성이 충족되는지」에는 영향을 주지 않으므로, 런타임에 인터셉터를 설치·조정·제거하더라도 리로드가 트리거되지 않습니다.

두 번째: 신뢰할 수 없는 코드는 반드시 격리 경계 밖으로 날려야 한다. 언어 수준의 검사는 악성 코드를 막을 수 없습니다——호스트 런타임에 손이 닿기만 하면 하위 객체를 직접 조작할 수 있어 검사가 무용지물이 됩니다. 진정한 격리에는 언어 계층 바깥의 실행 경계가 필요합니다. 소프트웨어 장애 격리(SFI), 격리된 언어 런타임, 샌드박스 프로세스, 가상화 컨테이너 등입니다. 신뢰할 수 없는 컴포넌트는 자체 격리 컨텍스트 안에서 실행되고, 「브리지」를 통해 호스트가 제공하는 의존성에 접근합니다. 이것은 사실 5.1절의 프로세스 간 호출의 일반화입니다——동일한 투명성 논증에 의해 브리지 접근과 로컬 인젝션은 구분되지 않습니다. 호스트 쪽에서 볼 때 브리지는 그저 평범한 파이버일 뿐이며, 그 케이퍼빌리티 범위는 위의 접근 제어로 더 좁힐 수 있습니다.

1.3 언어 독립성: 어떤 언어로도 이 패러다임을 구현할 수 있는가?

Cordis는 TypeScript로 구현되었지만, 패러다임 자체는 언어와 무관합니다——「시공간적 합성성」은 두 개의 차원으로만 정의됩니다. 각 차원에는 어떤 능력이 필요할까요?

시간 차원(분해하더라도 원래대로 복원 가능)에는 두 가지가 필요합니다.

  • 클로저——가역 이펙트는 연산과 그 역연산을 짝지어 줍니다. 역연산과 복원할 상태는 「값으로 포획」되어 있어야 분해 시점에 재실행할 수 있습니다. 이것이 최소 요구 사항입니다.
  • 런타임에 코드를 로드·언로드하는 능력——언어의 실행 모델에 따라 다릅니다. 관리 런타임은 프로그래밍 가능한 모듈 레지스트리에 의존합니다(예: Node.js의 require.cache. 모듈은 퇴출될 수 있고 참조가 없어지면 회수됩니다). 네이티브 코드는 명시적인 동적 링크와 언링크에 의존합니다(Unix의 dlopen / dlclose, Windows의 LoadLibrary / FreeLibrary). WebAssembly는 임베더가 어느 길을 택하느냐에 달려 있습니다. 어느 경우든 가역 이펙트는 「로드」를 컨텍스트에 적용되는 이펙트로 취급하며, 그 역연산은 모듈이 도입한 심볼·타입·핸들러 등록을 취소합니다.

공간 차원(의존성 자동 조정)은 본질적으로 「의존성 주입(DI)」 문제이며, 언어에 따라 다른 두 개의 층에서 펼쳐집니다.

언어에 필요한 것
타입 층「타입이 잘 맞는 의존성 접근」을 표현: 컨텍스트 타입은 각 키의 코이펙트를 기록해야 하고, 프로바이더가 이를 확장할 수 있어야 함Haskell 타입 클래스, Rust 트레이트(trait), TypeScript 모듈 확장(module augmentation)
런타임 층접근을 동적으로 중재: 프로바이더가 로드·언로드되면 키 뒤의 코이펙트가 바뀜JavaScript의 Proxy, Python의 디스크립터 프로토콜. 없으면 런타임 리플렉션을 사용(타입 안전성과 개발 경험을 희생)

더 편한 방법은 메타프로그래밍입니다. 어노테이션과 데코레이터가 메타데이터를 선언에 붙이고, 프로세서가 이를 중재를 담당하는 접근자로 펼칩니다. 컴파일 타임 메타프로그래밍(Rust 프로시저 매크로, Scala 매크로, Zig의 comptime)은 심지어 의존성마다 타입이 붙은 선언과 접근자를 생성할 수 있어 범용 인터셉션 프리미티브조차 필요 없습니다.

1.4 컴포넌트 세분성: 의존성 사이클을 어떻게 끊을 것인가

리액티브 코이펙트 모델에서 의존성 사이클(A는 B가 제공하는 키를 필요로 하고, B는 A가 제공하는 키를 필요로 함)은 양쪽 모두를 영구히 비활성 상태에 머물게 합니다——만족 술어가 영원히 참이 될 수 없기 때문입니다. 데드락과의 차이에 주의하세요. 데드락은 런타임 오류이지만, 의존성 사이클은 정적으로 예측 가능하고(의존성 선언만 봐도 알 수 있음), 런타임 오류를 만들지 않으며, 그저 「조용히 시작하지 않을 뿐」입니다.

어떻게 끊을까요? 겉보기에 상호 의존적인 관계의 대부분은 더 세밀한 컴포넌트로 분해하여 사이클을 없앨 수 있습니다. 논문의 예: 서버(네트워크 인터페이스 제공)와 접근 제어기(인가 정책 시행)가 양방향으로 상호작용합니다——접근 제어기는 서버에 도달하는 요청을 중재하고, 서버는 정책을 수정하는 엔드포인트를 공개합니다. 모놀리식 설계에서는 반드시 상호 의존이 생깁니다. 분해하면 네 개의 컴포넌트가 나옵니다.

  • server-core(네트워크 인터페이스 제공)
  • access-control-core(인가 정책 시행)
  • request-mediation(두 코어 모두에 의존하며, 들어오는 요청에 접근 제어를 적용)
  • policy-management(두 코어 모두에 의존하며, 서버를 통해 정책 수정 기능을 공개)

두 코어 컴포넌트는 서로 의존하지 않고, 「통합 컴포넌트」만이 양쪽 모두에 의존합니다——사이클이 사라졌습니다.

대가는 무엇일까요? 일반적으로, 상호작용하는 컴포넌트가 n개라면 통합 컴포넌트의 수는 n에 대해 제곱으로 늘어날 수 있습니다(양방향 상호작용의 각 쌍이 방향마다 하나씩 컴포넌트를 필요로 할 수 있으므로). 다행히 컴포넌트는 가벼워서 정확성과 성능에는 영향이 없고, 오히려 더 세밀한 세분성은 이점을 가져오기도 합니다——사용자가 자신에게 필요한 통합 바인딩만 로드할 수 있습니다. 진짜로 영향을 받는 것은 개발자 경험입니다——설정이 늘고, 이름 짓기가 늘고, 인지 부하가 높아집니다. 완화 방법은 모두 엔지니어링 수단입니다. 패키지 번들링(관련된 세밀한 컴포넌트를 하나의 설치 가능 단위로 묶기), 규약 기반 어셈블리(이름이나 타입이 어떤 패턴에 맞는 컴포넌트를 자동으로 연결), 스캐폴드 도구(선언적 명세로부터 상용구 통합 컴포넌트를 생성).

1.5 의존성 타입과 버전 관리: 키 충돌과 인터페이스 드리프트

형식 모델에서 의존성 링크는 전적으로 「키 동일성」으로 성립합니다. 키 k를 제공하는 컴포넌트는 k를 선언하는 어떤 컴포넌트든 만족시킵니다. 타입 패밀리 𝒱ₖ는 단일 컴파일 단위 내부의 타입 일관성을 보장할 수 있습니다——하지만 컴포넌트들이 각각 독립적으로 개발·빌드될 때(생태계의 통상), 이 보장은 물러나며 두 가지 문제가 생깁니다.

문제무엇인가결과
인터페이스 드리프트프로바이더가 개정할 때 키 k에 연관된 인터페이스를 변경하고(필드 추가, 메서드 시그니처 변경, 동작 계약 변경), 이전 인터페이스에 대해 컴파일된 컨슈머는 여전히 같은 키 k를 선언함의존성은 코이펙트 층에서 「충족」되었지만, 런타임 값은 더 이상 기대와 맞지 않음: 타입 오류, 메서드를 찾을 수 없음, 조용한 동작 이탈
키 충돌독립적으로 개발된 두 프로바이더가 전혀 무관한 인터페이스에 같은 키 이름 k를 사용함컨슈머가 호환성 검사 없이 다른 프로바이더의 값을 받아들임. 기대하는 타입과 실제 타입은 아무 관계도 없고, 장애는 예측 불가능하고 진단이 어려움

두 문제는 같은 공백을 가리킵니다. 코이펙트 모델은 명칭 기반 링크(키 이름에 의한)만 제공하고, 버전 기반 링크나 구조적 링크는 제공하지 않습니다. 논문은 세 가지 보완 방법을 제시합니다(「인프라와의 결합도가 강한 순서」로).

방법방식장점비용·한계
키 네임스페이스화키 공간을 K에서 K × P로 확장(P는 인터페이스를 정의하는 패키지를 식별)구조적으로 키 충돌을 제거함결합이 가장 강함: 키 동일성이 외부 패키지 레지스트리에 의존함
피어 의존성(peer dependency)호스트 언어의 패키지 매니저로 버전 제약을 선언(Cordis가 현재 채택한 방식)버전 비호환성이 설치 시점에 발견되어 런타임 장애로 끌려가지 않음. 의미론적으로는 「의존성을 내부에 번들하지 않고 런타임 컨텍스트가 제공하기를 기대한다」①프로바이더가 시맨틱 버저닝 규약을 자발적으로 지킬 것에 의존(강제 불가). ②패키지 매니저는 보통 하나의 의존성에 하나의 버전만 해석하므로 같은 패키지의 서로 다른 버전을 동시에 로드할 수 없음
구조적 호환성「키가 의존성에 있는가」를 「프로바이더의 인터페이스가 컨슈머의 기대를 구조적으로 커버하는가」로 교체완전히 언어 비의존적. 레코드 타입은 자연스러움(너비 서브타이핑)동작 계약이 복잡함(사전 조건, 사후 조건). 파라메트릭 다형성의 유계 양화를 도입하는 순간 결정 불가능해짐

세 가지 방법은 각각 한 측면을 담당하며, 이들을 하나의 의존성 모델로 통일하는 것은 여전히 미해결 문제입니다.

2. 관련 연구의 위치: Cordis는 지도의 어디에 서 있는가

제6장은 Cordis를 이웃 연구 분야들과 하나씩 대조합니다. 핵심은 이 한 문장입니다. 많은 시스템이 「부분적인 동적 조합」을 해결해 왔지만, Cordis만이 「가역 + 리액티브」를 동시에 런타임 메커니즘으로 만들었다. 아래는 「누가 누구인지」 요약표입니다.

관련 방향한 문장 설명Cordis와의 가장 큰 차이
Effekt, 대수적 이펙트(이펙트는 곧 케이퍼빌리티)이펙트 타입을 「계산이 컨텍스트에 무엇을 제공해 달라고 요구하는가」로 재해석함목적이 다름: Effekt가 이펙트를 드러내는 것은 모듈식 해석을 위해서(같은 연산에 여러 핸들러 의미론). Cordis는 추적과 취소를 위해서(모든 컨텍스트 변환에 역을 대응). Effekt는 타입 층에서 이펙트를 정적으로 규약함. Cordis는 런타임에 규약함
가역 이펙트 의미론(Heunen 등)대거(dagger) 화살표·역 화살표로 가역 환경에서 부수 효과를 모델링함가역성은 전역 속성(계산 전체가 가역). Cordis는 각 원자적 이펙트에 역이 있기만을 요구하고, 복합 이펙트의 역은 조합으로부터 도출함
등급 타입(Granule)등급 모나드 + 등급 코모나드로 계산이 「무엇을 하는가」와 「무엇을 필요로 하는가」를 동시에 추적함전부 타입 층이고 스코프는 어휘적으로 고정됨. Cordis는 같은 개념 쌍을 런타임 메커니즘으로 끌어올려 동적 조합을 다룸
COP(컨텍스트 지향 프로그래밍)언어에 「레이어」를 추가해 실행 컨텍스트에 따라 런타임에 동작을 활성화·비활성화함이름만 비슷함: COP의 컨텍스트는 주변 상황이고, 레이어는 부수 효과를 추적도 취소도 하지 않음. Cordis의 컨텍스트는 이펙트와 코이펙트를 중재하는 실체이며, 활성화는 의존성 만족성에 의해 구동되고, 비활성화는 완전히 취소함
AOP(애스펙트 지향 프로그래밍)포인트컷으로 조인 포인트를 양화하고 어드바이스를 직조하여 횡단 관심사를 처리함AOP는 대상이 무관심(oblivious)하며 임의의 조인 포인트에 매칭할 수 있음. Cordis는 횡단을 컴포넌트가 능동적으로 선언한 코이펙트로 제한함——결정적이고 추적 가능하며 컴포넌트 라이프사이클과 함께 취소됨
DSU, 핫 업데이트(webpack HMR 등)컴포넌트를 제자리에서 업데이트하고, 손으로 작성한 마이그레이션 함수로 상태를 앞으로 이전함Cordis는 마이그레이션 함수가 필요 없고, 완전한 언로드와 리소스의 완전한 복원을 지원함(대가: 장수명 의존성에 넣지 않는 한 리로드 후 메모리 상태는 보존되지 않음)
OSGi, iPOJO(가용성에 대한 반응)서비스가 나타나고 사라질 때 컴포넌트를 자동으로 활성화·비활성화함복원은 손으로 작성한 동기 비활성화 콜백에 의존하며, 빠뜨리면 조용히 누수됨. Cordis의 비활성화는 누적된 이펙트를 자동으로 취소하고, 관성 Unload 상태가 비동기 분해를 끝까지 수행함
DI 프레임워크, React Context초기화 시에 의존성을 주입하고 컴포넌트 트리를 따라 전달함프로바이더가 교체되거나 철회되어도 리액티브하게 재해결되지 않으며 라이프사이클 관리도 없음——바로 이 지점이 Cordis의 리액티브 코이펙트가 채우는 공백임
FRP(시그널, 리액티브 값)의 단위로 변화를 전파함Cordis는 컴포넌트 단위로 동작하며, 값 수준 전파가 모델링하지 않는 비동기 라이프사이클 의미론을 추가함. 둘은 상호 보완적이며 코이펙트 자체가 리액티브 값을 담을 수도 있음
STM, RAII, 가역 언어미리 고정된 스코프 안에서 이펙트를 자동으로 반전함반전의 범위가 정적으로 고정되어 있음. Cordis는 스코프를 전제하지 않고 컴포넌트 라이프사이클 내에서 임의의 컨텍스트 연산을 취소함

🎁 암기 팁: 이웃들은 「컴파일 타임에만 관리하거나」(등급 타입, Effekt), 「설치만 관리하고 해제는 관리하지 않거나」(OSGi 콜백, DSU), 「분해의 범위가 고정되어 있습니다」(STM, RAII). Cordis의 독점 영역은: 런타임의, 임의 스코프의, 설치도 깔끔하고 제거도 깔끔한 동적 조합입니다.

3. 결론 돌아보기: 두 개의 차원, 하나의 패러다임

제7장은 논문 전체를 네 문장으로 압축합니다.

  1. 가역 이펙트가 시간 차원을 해결한다——모든 컨텍스트 변환에 명시적 역을 갖추고, 이펙트 추적이 조합 연산을 보존함을 증명하여, 「컴포넌트가 제거될 때 상태를 완전히 복원한다」를 보장한다.
  2. 리액티브 코이펙트가 공간 차원을 해결한다——타입이 있는 의존성 컨텍스트를 형식화하고, 만족성 기반 알림, 코이펙트 격리, 인터셉션을 갖추어, 「의존성이 갖춰져야 시작하고 의존성이 없어지면 자동으로 멈춘다」를 개발자의 자율이 아닌 구조적 보장으로 만든다.
  3. 라이프사이클 모델이 둘을 꿰맞춘다——여러 제어 흐름에 적응하는 직교 확장으로서, 두 메커니즘의 상호작용에 작동 의미론을 부여하고 통합 컨텍스트 타입을 도출하여, 이펙트 컨텍스트와 코이펙트 컨텍스트를 하나의 일관된 프로그래밍 패러다임으로 통합한다.
  4. 구현과 검증——Cordis 메타프레임워크: 코어 라이브러리가 이펙트 추적과 코이펙트 해결을 담당하고, 선언적 컴포넌트 로더가 설정 조정과 핫 모듈 교체를 담당한다. Koishi 사례 연구가 4000개 이상의 커뮤니티 플러그인을 보유한 프로덕션 시스템에서 설계를 검증했다.

미래 방향에 대해 논문은 아주 SF적인 곳을 가리킵니다. 자기 진화 에이전트 프레임워크——거의 인간의 감독 없이, 자신의 프레임워크 컴포넌트를 지속적으로 생성하고 교체해 나가는 AI 에이전트입니다. 이러한 환경에서 Cordis를 사용하는 것은 바로 두 차원의 궁극적 약속을 검증하는 일입니다. 컴포넌트의 빠른 교체 시의 시간적 보장(완전한 복원), 그리고 토폴로지가 빈번히 변화할 때의 공간적 보장(의존성 조정)입니다. 복원 가능하고, 조정 가능하며, 지속적으로 자기 진화할 수 있는 것——이것이 이 패러다임이 되고자 하는 「자율 시스템의 기반」입니다.

动态组合时间可组合性拆了能还原空间可组合性依赖自动协调副作用完整撤销依赖齐了才启动

两个维度互相独立(正交):一个管「拆了干不干净」,一个管「组件怎么协调」

4. 핵심 포인트 정리

  1. 서비스 프록시가 독점 바인딩보다 낫다: 프록시는 고정된 진입점으로서 교란을 흡수하고, 로드 밸런싱·롤링 업데이트·프로세스 간 호출 3종 세트를 가져온다.
  2. 보안 두 가지 세트: 의존성 선언은 곧 케이퍼빌리티 요청(인터셉션과 결합해 세밀한 정책을 만든다). 신뢰할 수 없는 코드는 외부 격리 경계가 필요하다.
  3. 언어 독립성: 시간 차원에는 「클로저 + 모듈 레지스트리(또는 dlopen 같은 메커니즘)」가 필요하고, 공간 차원에는 「DI + 타입 계층 + 접근 중재」가 필요하다.
  4. 의존성 사이클은 분해할 수 있다: 양방향 상호작용을 「코어 컴포넌트 + 통합 컴포넌트」로 분해한다. 대가는 컴포넌트 수가 제곱으로 늘 수 있다는 것이며, 패키지 번들링 같은 엔지니어링 수단으로 완화할 수 있다.
  5. 버전 관리 세 가지 방법: 키 네임스페이스화(충돌 방지), 피어 의존성(Cordis의 현재 방식), 구조적 호환성(이상적이지만 어려움).

🎓 마치며: 2장(Cordis 논문 정독)을 마친 여러분은 다음 질문에 답할 수 있어야 합니다——「동적 조합의 두 차원은 무엇인가? 왜 컴포넌트를 나눌 때 『시간』과 『공간』을 함께 이야기해야 하는가?」「가역 이펙트와 리액티브 코이펙트는 각각 무엇을 해결하며, 무엇에 근거해 성립하는가?」「컴포넌트의 일생(라이프사이클)은 어떻게 관리되며, 언로드가 깔끔함이 왜 보장되는가?」「Cordis는 논문을 어떻게 실행 가능한 코드로 만들었고, Koishi에서 어떻게 검증되었는가?」「Effekt, AOP, DSU 같은 이웃들과 정확히 무엇이 다른가?」모두 답할 수 있다면——축하합니다, 여러분은 이제 『논문을 읽은 사람』입니다. 다음 단계는 1장으로 돌아가 DSH가 이 모든 것을 어떻게 실제 에이전트 프레임워크로 만들어 가는지 살펴하는 것입니다.

셀프 테스트 · 토론과 정리

답을 모두 선택한 후 「답안 제출」을 클릭하면 정답 여부와 해설을 확인할 수 있습니다.

1. 「서비스 프록시」와 「독점 바인딩」에 관해 올바른 설명은 무엇입니까?
2. 두 컴포넌트 A, B가 서로 상대방이 제공하는 키를 필요로 할 때(의존성 사이클), 어떤 일이 일어납니까?
3. 「인터페이스 드리프트」란 무엇을 가리킵니까?
4. Effekt나 등급 타입 같은 연구와 비교할 때, Cordis의 가장 큰 차이는 무엇입니까?