자바스크립트로 배우는 SICP - 22. 전선객체와 예정표, 그리고 제약조건의 전파
전선 객체, 예정표(agenda), 그리고 제약조건에 따라 값이 구해지는 방법에 대해 알아봅시다!
2024-10-13 | 독서 | 12min
오늘은 전선 객체와 agenda 그리고 제약조건에 따라 값이 구해지는 방법에 대한 내용이다!
전선 객체와 예정표
전선 객체
우선 전선 객체란 무엇일까? 전선 객체는 지역 상태 변수가 두 개인 계산 객체이다. 이 두 상태 변수는 신호 값을 담는 signal_value
와 신호 값이 변할 때 실행될 작용 함수들을 담는 action_functions
으로 나뉜다. 그럼 코드부터 보자!
function make_wire() {
let signal_value = 0; // 신호 값을 담는다! 초기 값은 0이다.
let action_functions = null; // 신호 값에 따른 작용 함수들을 담는다!
function set_my_signal(new_value) { // 새로운 신호 값이 들어왔을 때, 신호 값을 갱신하고, 작용 함수들을 실행하는 함수이다.
if (signal_value !== new_value) {
signal_value = new_value;
return call_each(action_functions); // 작용 함수 목록 내 모든 함수들을 호출하는 함수이다.
} else {
return "done";
}
}
function accept_action_function(fun) { // 작용 함수들을 추가하는 함수이다.
action_functions = pair(fun, action_functions); // 현재까지의 작용 함수들에 앞단에 새로운 함수를 추가한다.
fun(); // 그리고 들어온 작용 함수를 한 번 실행한다.
}
function dispatch(m) {
return m === "get_signal"
? signal_value
: m === "set_signal"
? set_my_signal
: m === "add_action"
? accept_action_function
: error(m, "unknown operation -- wire");
}
return dispatch;
}
다시 돌아와, 위 함수를 이용하면 앞서 make_wire
함수를 이용한 시뮬레이터 구현을 다룰 수 있게 된다!
예정표
이제 하나가 남았다. 이전에 새로운 신호가 적용되기까지 그 딜레이가 존재했다. 이를 after_delay
라는 함수가 역할을 한다고 해보자.
이를 위해 agenda
라는 새로운 데이터 객체가 필요하다! 역시 데이터 객체이기에, 생성자/변경자/선택자/술어 등의 조건들이 필요하다.
- 생성자 :
make_agenda
- 빈 예정표를 만들어서 돌려준다. - 술어 :
is_empty_agenda
- 예정표가 비어있는지 여부를 알려준다. - 선택자 :
first_agenda_item
- 예정표의 첫 항목을 돌려준다 - 변경자
remove_first_agenda_item
- 예정표의 첫 항목을 제거한다.add_to_agenda
- 주어진 함수를 주어진 시간에 실행하는 항목을 예정표에 추가한다
current_time
: 현재 시뮬레이션의 시간을 돌려준다
위가 구현되었다고 가정하고, after_delay
라는 함수를 구현하면 다음과 같다!
function after_delay(delay, action) {
add_to_agenda(delay + current_time(the_agenda),
action,
the_agenda);
}
코드는 우선 the_agenda
라는 현재 예정표 객체를 필요로 한다!(어디에 더할지는 알아야 되기 때문이다!)
그리고, 주어진 시간에 주어진 함수를 실행하는 조건을 추가해야되기에 current_time
함수를 이용하여 현재 예정표 객체에 대한 시간을 구하고 delay
값을 더해서 주어진 시간을 구한 뒤, 현재 예정표 객체까지 전달하면 드디어 주어진 시간
에 주어진 함수
를 실행하도록 어떤 예정표 객체
에 더할지 조건들을 완성했다. 이제 이를 add_to_agenda
라는 함수를 이용해 어떤 작업을 할 지 명시할 수 있다!