기록/2019-06-02
< 기록
둘러보기로 가기
검색하러 가기
- (lifthrasiir) 연산자 이름을 유지해야 할 필요성을 느끼지 못하고 있다.
- 원래 의도는 Python magic method(
__add__
)나 C++ operator name(operator +
)와 유사하면서 좀 더 체계적으로 정해지는 이름(#+#
또는+#
,#
가 피연산자 위치)을 원했던 것이었다. 어느 정도는 Coq/Agda 스타일 notation을 따라한 것도 있었다. - 그런데 "특정 연산자를 구현하는 타입" 같은 걸 타입 시스템에 포함하기 시작하면 interface든 trait든 뭔가 연산자를 나타내는 타입 상의 주체가 있어야 하는데, 그럼 굳이 특수한 이름이 필요한 게 아니라 그 주체랑 매어 놓으면 되는 거 아니냐? 싶은 것. (예: 러스트는
+
연산자가std::ops::Add
trait의add
method) - (Kroisse) 하스켈과 같은 모델은 어떤가? 연산자 생성은 자유롭고, 연산자 자체는 특수한 함수 이름으로 취급되는 것.
- (lifthrasiir) 그렇게 바꿀 수도 있을 것 같은데 "굳이" 그렇게 해야 하냐면 또 모르겠다. 일단은 연산자 이름이 없다고 가정하고 작업을 해 보도록 하겠다.
- 원래 의도는 Python magic method(
- (Kroisse) 연산자 오버로딩을 하게 되면 multiple dispatch는 어떻게 되는가? 이것도 연산자 이름에 영향을 줄 것 같은데.
- (lifthrasiir) 가능하면 symmetric multiple dispatch를 하고 싶다. 여기서 symmetricity라는 건 이를테면, 자바에서는 receiver(self)와 다른 인자가 dispatch에 다른 규칙을 적용받고, self와 다른 인자를 뒤집으면 다르게 resolve되는 경우가 있는데, 그렇게 하지 않겠다는 것이다. 그런데 이게 많이 까다롭다; 이렇게 동작하는 언어가 드물다는 것만 봐도 알 수 있다.
- (lifthrasiir) 일부 언어는 어떤 함수는 선언 순간 확정되고, 어떤 함수는 multiple dispatch가 가능하도록 확장되게 할 수 있다. 대표적으로 Perl 6에서 sub/multi 구분이 있다. 비슷하게
var
로 선언된 함수는 고칠 수 있고 그렇지 않은 함수는 고칠 수 없게 할 수 있지 않을까.- (lifthrasiir) 이거 써 놓고 나니까 OCaml 4+의 extensible variant와 굉장히 유사한 것 같다. 이게 본래 3.xx대에서는 exception type이라고 variant를 지속적으로 추가할 수 있는(하지만 실행 시간엔 그 목록이 확정되는) 특수 타입이 있었는데, 그걸 일반화한 것.
- (Kroisse) 그거 자바 checked exception과 비슷한 거 아닌가;;;
- (lifthrasiir) 함수마다 그 함수가 반환할 수 있는 exception list를 가지고 있는 게 아니므로 다르다. 굳이 그거랑 비교하자면 Zig의 error set type이 비교할만 하다. 개인적으로는 Zig의 이 컨셉은 checked exception의 현대적인 재해석이라고 생각한다.
- (Kroisse) Swift에서는 한동안 러스트 Option에 대응하는 타입만 존재하다가, 결국 throws를 붙여서 (나루의 실패에 대응하는) 오류를 반환할 수 있는 함수를 만들었다. 그 뒤에 Result에 대응하는 타입도 뒤늦게 추가되어 결과적으로 오류 처리 방법이 3가지...
- (lifthrasiir) C++ noexcept를 뒤집은 것과 유사한가? (주: 말할 때 실수로 nothrow라고 말했었음)
- (Kroisse) 그렇게 생각할 수 있겠다. Result와는 달리 반환 타입이 바뀌지 않는다.
- (lifthrasiir) 일종의 effect system이네;;;
- (Kroisse) 솔직히 async/await 수준...
- (lifthrasiir) 비슷한 맥락에서 나루에서는 함수와 메소드 구분이 희박한데, 단적으로 러스트 trait처럼 메소드도 영역scope에 매여 있어서 영역을 들이지 않으면 메소드를 쓸 수 없고 한정된 영역 안에서만 존재하는 기존 타입에 대한 메소드도 만들 수 있어야 한다고 본다.
- (Kroisse) 적어도 의미론단에서는 모두 복사가 일어나고, 내부적으로 copy-on-write하는 식으로 최적화만 해야 하지 않겠는가?
- (lifthrasiir) 나도 비슷하게 생각함. 예전 스펙 보면 reference에 대한 내용이 있고
@
연산자가 존재하는데 이 연산자를 안 쓰면 모두 복사한다는 뜻이다. 대부분의 타입은 복사가 일어나야 한다. - (Kroisse) 복사가 일어나면 안되는 타입이 있는가?
- (lifthrasiir) 뭐 예를 들면 파일 디스크립터 같은 것은... 아 물론 이론적으로는 복제 가능하지만ㅋㅋㅋㅋㅋ 좀 무리수 같기도.
- (Kroisse) 그러한 것들은 생각해 보면 캡슐에서 관리해야 할테니 굳이 그걸 고려해야 할 필요는 없을 듯?
- (lifthrasiir) 아 그럼 캡슐은 파일 디스크립터(등)의 핸들만을 유저 코드에 노출시킨다? 그거 그럴듯한 방법 같다. 고려해 보겠다.
- (lifthrasiir) 나도 비슷하게 생각함. 예전 스펙 보면 reference에 대한 내용이 있고
- (ditto) mutable한데 복사가 기본이면 좀 헷갈린다고 생각하긴 한다
- (lifthrasiir) 원 의도는
@
연산자를 쓸 때만 변경이 일어난다는 것이었다(변수는 제외). 예를 들어서x := (a: 1, b: 2, c: 3)
이면x a = 4
같은 건 불가능한 것이고,x := new (...)
로 선언되어 있어야만x@ a = 5
같은 게 가능한 것이다(레코드가 변경 가능하다고 가정할 경우, 이건 아직 결정되지 않음). - (lifthrasiir) 망해서 오픈소스가 된(...) 페이스북의 Skip 언어의 mutability 접근이 내 생각과 굉장히 유사하다. http://www.skiplang.com/docs/mutability.html
- (lifthrasiir) 원 의도는
- (disjukr) FFI가 어려워지지 않을까?
- (Kroisse) FFI 자체를 데이터 드리븐으로 만드는 식으로 피해갈 수 있다고 본다. 그렇게 되면 필연적으로 나루 코드와 외부 통신은 직렬화로 일어나게 될 것이고 변경 가능한 값은 오가지 않게 된다. wasm과 유사함
- (lifthrasiir) 이론적으로는 그러한데, 그런 모델을 쓰면 망하는 경우가 좀 있다(OpenGL 따위). wasm에서도 성능 문제 때문에 direct C FFI를 고려하고 있는 걸로 알고 있는데...
- (Kroisse) 결국 low-level FFI와 high-level FFI(캡슐을 통하는)가 나뉘지 않을까?
- (Kroisse) object type 같은 것은 존재할 예정인가?
- (lifthrasiir) 기본으로는 structural하고, 그런 타입을 nominal하게 만드는
new type
선언이 예정되어 있다. 예를 들어서Date := new type (year: int, month: int, day: int)
- (lifthrasiir) 정확한 문법 등은 용례를 보고 고치게 될 것 같지만 어쨌든 이 타입은 본래의
(...)
레코드 타입과 별도가 되어 메소드 등도 따로 존재하게 된다.
- (lifthrasiir) 기본으로는 structural하고, 그런 타입을 nominal하게 만드는
- (Kroisse) 함수 클로저가 바깥의 값(upvalue)을 close하면,
var x := ...
따위로 선언된 upvalue도 호출할 때마다 복사가 일어나야 하는가?- (lifthrasiir) 사람들이 생각하는 것과 크게 다를 듯. 나는
var x: T := ...
는 근본적으로x: T@ := new ...
의 desugaring이라고 본다(그리고x
가 사용되는 모든 곳이x@
로 바뀜). - (Kroisse) 이게 문제가 되는 건 개념적으로 값은 복사를 해야 하는데
a := fn { ... }; b := a
했을 때 a와 b가 내부적으로 공유 상태를 들고 있을 수 있기 때문이다. - (lifthrasiir) 좋은 지적이다. internal reference와 근본적으로 같은 문제를 공유하는 것 같은데 예상보다 subtle한 듯;;;
- (lifthrasiir) 사람들이 생각하는 것과 크게 다를 듯. 나는