Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

특성 #3

Open
Kroisse opened this issue Jun 21, 2019 · 0 comments
Open

특성 #3

Kroisse opened this issue Jun 21, 2019 · 0 comments

Comments

@Kroisse
Copy link

Kroisse commented Jun 21, 2019

요약

다형성을 위한 도구로 Rust와 비슷한 스타일의 특성(trait)을 도입하고, 나아가 하나의 타입만을 위한 메서드 선언도 특성 구현의 일종으로 취급하는 안을 제안합니다.

-- 새로운 특성인 BufRead를 정의
BufRead := trait declare(
    fill_buf: fn() -> Buffer@,
    cosume: fn(amount: nat),
)

-- 새로운 타입을 만들고 거기에 BufRead 특성을 구현
EmptyReader := new type (buf: Buffer@)
EmptyReader impl(BufRead,
    fill_buf: fn() -> Buffer@ {
        self buf
    }
    consume: fn(amount: nat) {
        -- do nothing
    }
)

-- 또는 EmptyReader만을 위한 메서드 구현을 정의할 수도 있습니다
EmptyReader impl(
	close: fn() {
    	-- ......
	}
)

동기

(WIP)

구체적인 설계

핵심 타입 trait를 추가하고, trait declare() 문법을 통해 새로운 특성을 만들도록 합니다. 이 경우, trait라는 값이 declare라는 이름의 메서드를 가지고, 그 메서드가 임의의 키워드 인자를 받는 것처럼 간주할 수 있습니다.

또한, 핵심 타입 typetype impl() 메서드를 추가하여 첫 번째 인자로 들어온 특성의 구현을 제공할 수 있도록 합니다.

특성 정의 및 구현 문법은 의도적으로 일반적인 나루 코드의 메서드 호출과 비슷한 형태로 만들었는데, 새로운 문법 요소를 추가하는 걸 최대한 피하면서 정적 실행 메커니즘만으로 구현이 가능하도록 하기 위함입니다.

컴파일 과정에서, trait declare()를 만나면서 특성 명세를 만들고 type impl()를 거치면서 개별 타입을 위한 가상 메서드 테이블을 구성할 수 있을 것입니다.

디스패치

(WIP)

  • 호출할 메서드 구현은 동적으로 디스패치될 수 있지만, 어떤 특성의 메서드를 호출하는지는 컴파일할 당시에 결정되어야만 합니다.
  • 이를 위해, 시야(scope) 안에서 접근 가능한 특성이 가진 메서드만 호출 가능하도록 제약을 둡니다.

문제점

제네릭 특성을 선언하거나, 제네릭 타입에 특성을 구현하는 문법을 만들기가 자명하지 않습니다. 보통의 제네릭 메서드 호출에서 제네릭 타입 인자에 구체적인 타입이 들어가는 것과는 달리, 특성 정의나 특성 구현을 추가하는 단계에서는 타입 변수 T가 필요하고, 이 이름이 어디에서 오는 것인지 불분명해질 가능성이 있습니다.

대안

특성 선언에 메서드 호출과 레코드 타입 문법을 재활용하는 대신, new type과 대칭이 되도록 만드는 방법이 있습니다. 문장 끝의 쉼표와 같은 거추장스러운 문법을 피할 수 있고, 제네릭 특성을 만드는 게 좀 더 수월해지는 대신, trait를 키워드로 새로 추가해야 하는 단점이 있습니다.

BufRead := new trait {
    fill_buf: fn() -> Buffer@
    cosume: fn(amount: nat)
}

풀리지 않은 의문

trait declare()로 새 특성을 만드는 게 가능하다면, 비슷하게 new type 대신 type define()처럼 타입 정의 문법을 바꾸는 것이 가능할 수 있습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant