본문으로 건너뛰기

© 2026 Molayo

GeekNews헤드라인2026. 06. 30. 09:22

Ante: 빌림 검사와 참조 카운팅을 결합하는 새 방식

요약

Ante는 참조 카운팅의 유연성과 빌림 검사의 안전성을 결합한 새로운 시스템 프로그래밍 언어 설계입니다. shape-stability와 temporary uniq conversion을 통해 Rust의 런타임 패닉이나 Swift의 독점 접근 검사 오버헤드 없이 안전한 가변 빌림을 구현하는 것을 목표로 합니다.

핵심 포인트

  • 참조 카운팅과 빌림 검사를 결합하여 메모리 및 스레드 안전성 확보
  • shape-stability 개념을 통해 동일 구조체에 대한 다중 가변 빌림 허용
  • Rust의 Rc<RefCell<T>> 패닉 위험과 Swift의 런타임 오버헤드 해결 시도
  • 컴파일 타임 규칙을 활용하여 공유 가변 빌림의 안전성 검증

Ante는 참조 카운팅 의 유연성과 빌림 검사 의 안전성을 함께 쓰면서, Rust식 런타임 패닉이나 Swift식 독점 접근 검사 오버헤드를 피하려는 시스템 언어 설계임
핵심 장치는 shape-stability 와 temporary uniq conversion으로, 참조 카운팅된 값의 필드에는 안전하게 가변 빌림을 만들고 유니언 내부 값은 제한된 범위에서만 uniq

로 다룸
Rust의 Rc<RefCell<T>>

는 잘못 사용하면 런타임에 패닉이 날 수 있고, Swift의 borrowing system은 런타임 독점 접근 검사를 포함하지만, Ante는 일부 사례를 컴파일타임 규칙으로 처리하려 함
아직 일부만 구현된 work-in-progress 설계이며, 타입을 재귀적으로 분석해 특정 객체에 도달 가능한지를 판단해야 하므로 필드 추가가 breaking API change가 될 수 있음
이 접근은 shared mutable borrowing이 항상 불가능하다는 전제를 약화시키며, Vale, group borrowing, Rust GhostCell 같은 기법과 함께 메모리 안전성 설계의 예외 영역을 넓히고 있음
Ante가 목표로 하는 결합
Ante는 메모리 안전성 과 스레드 안전성 을 갖춘 더 단순한 Rust를 목표로 하는 시스템 프로그래밍 언어임
기본 모델은 단일 소유권과 빌림 검사이며, 값은 스택이나 포함하는 구조체·배열 안에 인라인으로 놓임
단순성을 우선하고 싶을 때는 타입에 shared

키워드를 붙여 참조 카운팅 을 선택할 수 있음
shared type Color

, shared type RbTree t

를 사용한 red-black tree balance

함수는 Python 예시만큼 짧고 C++·Rust 예시보다 작음
핵심 관심사는 참조 카운팅된 데이터를 가변으로 빌릴 때 Rust의 borrow_mut()

패닉 위험이나 Swift의 런타임 독점 접근 검사 없이 처리하는 방법임
Ante는 아직 work-in-progress 상태이며, 일부는 구현됐고 일부는 이론적이며 설계도 변하는 중임
shape-stability와 여러 가변 참조
Ante의 shape-stability 는 “stable shape를 가진 대상에 대한 참조는 다른 곳에서 어떤 변경이 일어나도 항상 유효하다”는 개념임
이 개념 덕분에 같은 구조체에 대해 여러 개의 가변 빌림 참조를 동시에 가질 수 있음
heal (healer: mut Entity) (target: mut Entity)

예시에서는 같은 Entity

를 두 인자로 넘겨 자기 자신을 치유하는 self_heal

호출이 가능함
healer

target

이 같은 Entity

를 가리켜도 이 코드에서는 Entity

를 파괴할 수 없으므로 두 참조가 계속 유효함
구조체 자체와 그 필드, 필드의 필드에 대한 가변 참조도 동시에 허용될 수 있음
ship: mut Spaceship

engine_alias: mut Engine = ship.engine

를 동시에 사용해도, 함수 실행 중 ship

과 그 안의 engine

이 파괴되지 않는다고 판단함
Rust와 Swift에서는 같은 데이터에 여러 &mut

참조가 동시에 가리키는 형태를 허용하지 않음
참조 카운팅된 값의 필드 가변 빌림
Ante에서 타입 정의 앞에 shared

를 붙이면 해당 타입은 자동으로 참조 카운팅 됨
shared mut type Spaceship

예시에서는 launch

Rc

에 해당하는 Spaceship

을 보유하면서 mut ship.engine

set_fuel

에 넘김
launch

가 포함 객체인 Spaceship

을 유지하므로, 그 필드인 engine

도 살아 있다고 판단할 수 있음
일반 규칙은 shared mut

타입의 필드에 대해 항상 mut

빌림 참조를 만들 수 있다는 것임
단, 그 필드 안쪽에 들어 있는 모든 대상에 대해 항상 가변 빌림을 만들 수 있는 것은 아니며, 별도 규칙이 필요함
이후 예시는 설탕 문법인 shared mut type Spaceship

대신 더 명시적인 Rc Spaceship

표기를 사용함
shared mut type Spaceship

type Spaceship

이 되고, var ship: Spaceship

var ship: Rc Spaceship

이 됨
유니언이 안전성 문제를 만드는 지점
유니언은 내용을 인라인으로 보관해 포인터 추적과 캐시 미스를 줄일 수 있어 속도 에 유리함
C의 union Engine

struct Spaceship

안에 들어가면 StringTheoryEngine

ImpulseEngine

Spaceship

메모리 안에 위치함
Java처럼 인터페이스와 포인터를 사용하는 방식과 대비됨
문제는 메모리 안전 언어에서 유니언을 안전하게 지원하기 어렵다는 점임
Engine

StringTheoryEngine(str: String)

또는 ImpulseEngine(fuel: I32)

인 예시에서는 ship

other_ship

이 같은 Spaceship

을 가리킬 때 세그폴트가 날 수 있음
match uniq ship.engine

으로 문자열 내부 참조를 잡은 뒤
other_ship.engine := ImpulseEngine 0x42

로 같은 엔진을 다른 변형으로 바꾸고
이어서 기존 str

을 수정하면 컨테이너가 파괴된 뒤 내부를 사용하는 문제가 생김
따라서 Ante는 가변 빌림 참조가 유니언 을 가리킬 때 그 변형 중 하나에 대한 가변 빌림 참조를 만들 수 없도록 해야 함
이는 구조체 규칙과 반대임
구조체에 대한 mut

참조가 있으면 필드에 대한 mut

참조를 만들 수 있음
유니언에 대한 mut

참조가 있으면 변형 내부에 대한 mut

참조를 만들 수 없음
uniq

와 temporary uniq conversion
uniq

는 exclusive mutable reference , 즉 독점 가변 참조를 뜻함
어떤 변수가 uniq Spaceship

을 담고 있다면, 그 Spaceship

에 대한 유일하게 사용 가능한 참조임
Rust의 &mut Spaceship

과 비슷한 개념임
유니언 내부를 안전하게 다루기 위해 Ante는 temporary uniq conversion 을 사용함
핵심 규칙은 특정 범위에서 다른 별칭 가능 참조를 사용하지 않는다면 임시로 uniq

참조를 얻을 수 있다는 것임
match uniq ship.engine

구간에서는 ship.engine

에 대해 uniq

처럼 접근함
이 구간 동안 컴파일러는 Spaceship

을 간접적으로 포함할 수 있는 다른 기존 변수를 사용하지 못하게 함
Rust는 “다른 참조가 어딘가에 있을 수 있다”는 이유로 uniq

존재 자체를 막는 반면, Ante는 해당 범위에서 그 참조들을 사용하지 않는 조건 으로 uniq

를 허용함
이때 uniq Spaceship

은 실제로 전역적으로 유일한 참조가 아니라, 해당 범위 안에서 유일하게 사용 가능한 참조임
C의 restrict

포인터와 유사한 뉘앙스를 가짐
허용되는 접근과 거부되는 접근
match uniq ship.engine

범위 안에서 other_ship: Rc Spaceship

에 접근하면 컴파일 오류가 나야 함
other_ship.engine

ship.engine

과 alias일 수 있고
ship.engine

을 사용하는 동안 other_ship.engine

변경이 drop을 유발할 수 있기 때문임
HasAShip

처럼 Rc Spaceship

을 필드로 가진 다른 구조체도 같은 이유로 거부됨
other.ship.engine

도 간접적으로 같은 Spaceship

에 도달할 수 있음
반대로 new_fuel: I32

같은 정수는 사용할 수 있음
I32

Spaceship

에 대한 참조를 포함할 수 없기 때문임
Spaceship

자체가 follow_ship: Rc Spaceship

같은 필드를 포함하면 거부됨
그 경우 uniq Spaceship

도 자기 내부 경로를 통해 다시 도달 가능해지므로, 일반적으로 재귀 타입에는 mut -> uniq

변환을 할 수 없음
함수 호출과 반환에서의 제약
함수 호출에서도 mut -> uniq

변환이 일어날 수 있음
foo (var ship: Rc Spaceship) (new_res: Resonator)

maybe_use_resonator ship new_res

를 호출할 때, 호출 지점에서 ship

uniq Spaceship

으로 변환됨
컴파일러는 다른 인자가 Spaceship

참조를 포함할 수 있는지만 확인하면 됨
예시의 Resonator

는 그런 참조를 포함하지 않으므로 허용됨
반환에서는 변환된 uniq

참조를 일반 uniq

로 돌려줄 수 없음
반환 후에는 “범위 안에서 alias 가능 변수를 사용하지 않는다”는 컴파일러 검사가 적용되지 않기 때문임
대신 반환 타입을 local uniq Foo

로 지정할 수 있음
내부적으로 mut ref

에서 uniq ref

로 변환할 때 실제로는 항상 local uniq 가 만들어짐
대부분의 경우 일반 uniq

처럼 사용할 수 있지만, 반환할 때는 명시가 필요함
설계상의 비용과 대안
Ante는 Rc Spaceship

같은 참조 카운팅 참조를 런타임 오류 없이 임시 uniq Spaceship

으로 바꿀 수 있음
단점은 컴파일러가 “Engine

에서 Spaceship

에 도달할 수 있는가” 같은 질문에 답하기 위해 타입을 재귀적으로 살펴봐야 한다는 점임
이런 분석은 취약할 수 있음
구조체에 필드를 추가하는 일이 breaking API change 가 될 수 있음
Ante의 제작자인 Jake는 이 보장을 유지하는 더 나은 방법을 찾고 있음
group borrowing 과 Flix references 처럼 각 공유 가변 타입에 익명 고유 브랜드 타입을 붙이는 방식
공유 타입을 변경할 때 Mutates 'a

같은 effect를 추가해 타입 분석을 제거하는 방식
두 참조가 다른 객체를 가리키는지 사용자가 런타임에 검사하거나, safe API로 감싼 unsafe 검사를 제공하는 방식
컴파일러가 Rc

내부에 간접 저장되지 않아 alias될 수 없는 값을 추적하는 방식
Pony의 iso permission 과 비슷한 아이디어, 또는 구조체 내부를 보되 바깥을 가리키는 참조는 사용하지 못하게 하는 임시 권한도 가능성으로 남아 있음
어려운 부분은 이런 유연성을 유지하면서 Ante의 목표인 사용성 , 가독성 , 단순성 을 지키는 것임
더 넓은 메모리 안전성 흐름
shared mutable borrowing은 예전에는 불가능하다고 여겨졌고, Rust도 그런 믿음 위에 설계됐다는 관점을 깔고 있음
여러 예외가 누적되고 있음
Ante는 local uniqueness 규칙을 통해 shared-mutable 데이터에서 uniq

빌림 참조를 얻을 수 있음
Vale 은 pure function을 통해 shared-mutable 데이터에서 불변 빌림 참조를 얻을 수 있음
group borrowing 은 shape-stable이 아니어도 shared-mutable 빌림 참조를 만들 수 있음
Rust의 GhostCell 은 객체 그래프가 서로 자유롭게 가리킬 수 있게 하지만, 특정 시점에는 그중 하나에 대한 가변 참조 하나만 가질 수 있음
이 흐름은 메모리 안전성 설계에서 shared mutable borrowing을 다루는 더 일반적인 원리가 있을 가능성을 암시함
Rust Cell

과의 비교
Rust 사용자는 구조체 필드에 Cell

을 넣는 방식과 Ante 접근의 차이를 물을 수 있음
Ante 예시에서는 Rc Spaceship

에서 status: String

에 대한 mut String

참조를 얻어 " (refueling)"

을 직접 붙일 수 있음
Rust의 Cell<String>

방식에서는 Rc<Spaceship>

에서 &mut String

을 얻을 수 없음
대신 status_ref.replace(String::new())

로 임시 기본값을 넣고
꺼낸 String

을 수정한 뒤
마지막에 다시 replace(status)

로 되돌려야 함
이 방식에는 몇 가지 단점이 있음
""

같은 기본 인스턴스 를 만들어야 함
마지막 replace

호출을 잊을 위험이 있음
값이 교체된 상태에서 누군가 status

를 읽을 위험이 있음
Ante는 임시로 status

문자열에 대한 참조를 얻도록 하고, 그동안 다른 코드가 접근하지 못하게 컴파일러가 강제함
댓글과 토론

AI 자동 생성 콘텐츠

본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0