Sleeep23' space
Front-end Engineer

자바스크립트로 배우는 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 라는 함수를 이용해 어떤 작업을 할 지 명시할 수 있다!