December 16, 2020
본 포스트는 ReScript 공식문서를 스터디하며 정리한 포스트 입니다.
포스트를 작성하며 작성한 코드는 여기에서 확인할 수 있습니다.
ReScript에서의 Let Binding은 다른 언어에서의 변수 선언이라고 할 수 있다.
let gretting = "hello!"
let score = 10
let newScore = 10 + scores
위의 코드와 같이 let
키워드를 사용해 값을 이름에 바인딩한다.
ReScript에서는 {}
를 이용해 바인딩 범위를 지정할 수 있다. 블록 스코프 안에서 선언된 변수는 밖에서 접근할 수 없다.
let message = {
let part1 = "hello"
let part2 = "world"
}
// part1과 part2에 접근할 수 없다.
블록 스코프의 마지막 줄의 값은 암시적으로 반환된다.
let message = {
let part1 = "hello"
let part2 = "world"
pert1 ++ " " ++ part2
}
따라서 위 코드의 message
변수는 "hello world"
의 값을 갖게 된다.
// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';
var message = "hello world";
exports.message = message;
/* No side effect */
JavaScript로 컴파일된 결과는 위와 같으며 message
변수가 "hello world"
인 것을 확인할 수 있다.
ReScript의 if
, while
구문과 함수는 모두 동일한 블록 스코프 지정 매커니즘을 사용한다.
let displayGretting = true
if displayGretting {
let message = "Enjoying the docs so far?"
Js.log(message)
}
// message는 여기에서 접근할 수 없다.
앞에서 설명한 블록 스코프와 동일하게 모두 {}
를 이용해 블록 스코프를 지정한다.
Let Binding은 불변하며 “바뀔 수 없음”이라고 한다. 이런 불변함은 타입 시스템이 다른 언어보다 훨씬 더 많은 것을 추론하고 최적화할 수 있도록 돕는다.
바인딩이 불변하다는 것은 비현실적으로 들릴 수 있다. 바인딩된 값을 변경하기 위해서 사용할 수 있는 방법으로는 2가지가 있다.
아래의 JavaScirpt 패턴으로 예를 들 수 있다.
var result = 0;
result = calculate(result);
result = calculateSomeMore(result);
위 코드는 아래와 같이 작성해도 동일하게 동작하며 결과가 왜곡되지 않는다.
var result1 = 0;
var result2 = calculate(result1);
var result3 = calculateSomeMore(result2);
위 코드는 ReScript로 작성해도 확실히 동일하게 동작한다.
let result1 = 0
let result2 = calculate(result1)
let result3 = calculateSomeMore(result2)
JavaScript로 컴파일된 결과물 또한 위의 바로 위의 JavaScript 코드와 동일할 것이다.
let result = 0
let result = calculate(result)
let result = calculateSomeMore(result)
위와 같이 코드를 작성해도 동작하며 JavaScript로 컴파일된 코드는 아래와 같다.
var result = calculate(0);
var result$1 = calculateSomeMore(result);
추천하는 방법은 아니지만 아래의 코드 또한 유효하며 동작한다.
let result = "hello"
Js.log(result) // prints "hello"
let result = 1
Js.log(result) // prints 1
위의 코드는 JavaScript로 컴파일이 되면 result
변수는 마지막에 선언한 하나만 남게 된다.
var result = 1;
console.log("hello");
console.log(1);
실질적인 변형은 없으며 참조하는 바인딩은 위쪽에 가장 가까운 바인딩이 된다. 만약 값을 전달하거나 많은 코드들에 의해 진짜 변형이 필요한 경우 ReScript는 약간 더 무거운 변형 기능을 제공한다.
Private let bindingns은 7.2 버전 릴리즈에 도입되었다. ReScript의 모듈 시스템에서 모든 필드들은 기본적으로 public으로 사용된다. 값을 숨기는 유일한 방법은 public 필드와 필드 타입을 나타내는 별도의 시그니처를 작성하는 것이다.
module A: {
let b: int
} = {
let a = 3
let b = 4
}
위와 같이 모듈을 작성하게 될 경우 변수 int
타입의 변수인 b
만 public필드로 사용된다. JavaScript로 컴파일된 코드는 아래와 같다.
// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';
var A = {
b: 4
};
exports.A = A;
/* No side effect */
ReScript의 모듈 A
가 컴파일된 JavaScript 객체 A
에서 a
필드에 관한 데이터는 없이 컴파일 된 것을 볼 수 있다. 또한 %private
를 이용해 직접적으로 private 필드를 지정할 수 있다.
module C = {
%%private(let a = 3)
let b = 4
}
%private
는 파일 수준 모듈에도 적용되게 되며 컴파일된 결과는 시그니처를 제공하는 방법과 동일하다.
%private
를 사용하는 방법보다는 시그니처를 제공하는 방법은 별도의 컴파일 유닛을 더 잘 제공하며 문서화에도 적합해 권장된다. 하지만 %private
를 이용하는 방법은 아래와 같은 상황에서 유용하다.