Tuples -
튜플은 immutable하다. C/C++에서의 구조체, 파이썬의 tuple과 같이 Product types이다.
정의.
선언
tuple 은 "tuple" keyword, 대문자로 시작, 그리고 등호 사인으로 선언한다.
이름과 등호 사인 사이에 type parameter를 옵션으로 가질 수 있다.
선언은, constructor와 deconstructor의 범위 안에 정의된 "export" modifier 앞에 올 수 있다.
더 많은 설명은 여기를 참조하라Packages documentation.
Fields
colon이나 type 앞에 선행하는, 대문자로 시작하는 name을 가지는 fields는 하나 이상을 가질 수 있으며, 이는 Tuples을 구성한다(Tuples are composed of one or more fields, each of which has a name beginning with a capital letter followed by a colon, and a type. The types may correspond to declared type parameter).
각각의 필드는 (accessor functions의 범위를 정의하는)export modifier가 앞서서 올 수 있다.
Concrete Syntax
Example
Construction
튜플은 튜플 자체의 이름과 동일한 이름의 함수로 구성된다.
함수에는 필드 정의 순서대로 각 필드에 하나씩 N 개의 인수가 있다.
위의 Cat 정의에서 필드에서 export modifiers를 포함했지만 선언 줄은 포함하지 않았음을 알 수 있다.
constructor와 deconstructor를 private로 유지하는이 패턴은 Backwards Compatibility을 유지하는 확장 가능한 API를 만드는 데 도움이됩니다 (나중에 자세히 설명).
Deconstruction
튜플은 패턴 매칭에 사용될 수 있다. constructor와 마찬가지로, constructor는 튜플 이름 뒤에 각 필드를 사용한다.
위의 예제에서 match와 deconstruction을 사용하여 Name을 얻는 함수를 작성할 수 있다.
대안으로, def 구절에 scope에 variable을 bind할 수 있다.
더 간단하게로는, 함수 인자안에 tuple을 deconstruct 할 수 있다.
Accessor Functions
사용자 편의를 위해 Wake는 튜플의 각 필드에 대한 Accessor Functions(getter, setter, editor)를 생성한다.
함수 이름은 변형을 제안 할 수 있지만 Wake의 모든 유형은 변경 불가능하므로 모든 "set" or "edit" 함수는 새 튜플을 리턴한다. 생성 된 함수는 (get|set|edit)<tuple name><field name> 형식이다.
getter의 유형은 간단히 <tuple type> ⇒ <field type>이다.
위의 Cat 예제의 경우 getCatAge는 Cat ⇒ Integer type이다.
Setters는 <field type> ⇒ <tuple type> ⇒ <tuple type> 형태의 type이다.
이것은 1.필드에 대한 새 값과 2.새 튜플에 대한 이전 튜플, 이렇게 두 argument의 함수로 생각할 수 있다.
Cat의 경우 setCatName은 String ⇒ Cat ⇒ Cat type이며 다음과 같이 사용할 수 있다.
Type Parameterization
튜플은 소문자로 시작하는 identifier로 선언 된 type parameter를 지원한다.
이러한 parameters를 사용하면, 단일 튜플 정의를 통해 its memebers에 대해 서로 다른 types을 처리 할 수 있다.
예를 들어 표준 라이브러리의 "Pair tuple"을 생각하라.
Pair 은 일반적으로 Scala 또는 Python과 같은 언어에서 "tuple"이라고 부르는 것과 유사하다.
Pair 의 두 필드 각각에 대해 하나씩 두 개의 type parameters인 a와 b가 있다.
따라서 우리는 임의 유형의 Pairs 을 만들 수 있다.
Pair 3 "hi"는 Pair Integer String이고 Pair (_ + 1) (Cat "Bill" 4) 은 Pair (Integer ⇒ Integer) Cat이 된다.
실제로 type parameters는 주로 요소 유형별로 데이터 구조를 parameterize하는 데 사용된다.
Backwards Compatibility
아마도 tuple의 가장 중요한 사용 사례는 이전 버전과의 호환성을 유지하면서 시간이 지남에 따라 발전 할 수있는 유연한 API를 만드는 것이 될 것이다.
The Importance of Private Constructors and Deconstructors
Wake는 strongly and statically typed language이기 때문에, 함수에 argument를 추가하게 되면, 그것의 정의가 변경되어 모든 사용이 중단된다.
앞에서 설명한 것처럼 tuple의 constructor는 각 필드에 하나씩 N 개의 인수를 사용한다.
따라서 tuple에 필드를 추가하면, 생성자에 필드가 추가되고, 해당 생성자의 모든 사용을 변경해야한다.
그러나, tuple의 constructor와 deconstructor를 private으로 만들면 이러한 파손이 declaration package로 제한된다는 것을 보장 할 수 있다.
비판적으로, user 코드에서는 이러한 손상이 발생하지 않으므로 이전 버전과 호환되는 방식으로 API를 발전시킬 수 있다.
- Adding Fields to Tuples
constructor는 deconstructor를 비공개로 만들었다 고 가정하면 이전 버전과 호환되는 방식으로 튜플을 확장 할 수 있습니다. 필드를 추가 할 때 간단히 팩토리 함수를 업데이트하여 새 필드에 대한 기본값을 제공하면 새 API 사용자가 생성 된 접근자를 활용하여 활용할 수 있습니다.
예를 들어, 이전의 Cat 예제를 고려하라.
우리는 constructor는 deconstructor를 비공개로 만드는 선견지명을 가지고 있었고 대신 전역 팩토리 함수 만 노출했다. optional Owner 필드를 사용하여 Cat을 확장하려면 기존의 Cat 사용을 중단하지 않고 그렇게 할 수 있다.
선택적 소유자 필드를 사용하여 Cat을 확장하려면 기존의 Cat 사용을 중단하지 않고 확장 할 수 있다.
새 필드에 대한 기본값을 제공하도록 factory function을 업데이트한다..
이제 기존의 모든 Cat 사용은 계속 작동하면서, 사용자는 생성 된 접근자를 활용하여 새 필드를 사용할 수 있도록 설계할 수 있다.
- Deleting Fields From Tuples
필드를 제거하는 동안 이전 버전과의 호환성을 유지할 수도 있다.
주어진 필드에 노출 된 유일한 API는 생성된 접근자 함수이므로, 단순히 필드를 삭제하고 제거된 접근 자 함수를 구현할 수 있다.
물론 이러한 노력은 소스 호환성을 보장할뿐이다.
API를 계속 사용하면 유형 검사 및 실행이 계속된다.
API를 사용하는 실제 코드에 대한 guarantee는 없기때문에, 기능 삭제는 매우 주의해서 수행해야한다.