본문 바로가기
C.W.K.
Stream
Lesson 02 of 04 · published

결정론은 Rust 로

~11 min · rust, deterministic, file-io, tauri-command

Level 0식은 초고
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"같은 입력이 항상 같은 출력을 내야 하는 일이면 Rust 몫이야. 빠르고, 테스트가 되고, 절대 추측하지 않으니까."

Rust 코어에 사는 것

봉합선에서 결정론 쪽에 있는 건 전부 Rust 코어에 살아. 부활한 WordPress-tag 레이어인 export ruleset 적용, frontmatter 와 태그를 읽고 쓰기, 파일 읽고 쓰기. 전부 순수한 변환이야. 문서에 ruleset 을 더하면 출력이 정확히 하나 나오고, 언제 돌려도 똑같아. 모델도 없고 무작위성도 없고 '경우에 따라' 도 없지. 그 성질 덕분에 아무한테도 안 물어보고 돌려도 안전한 거고.

왜 결정론에 Rust 인가

Rust 가 결정론 레이어에 맞는 이유가 셋이야. 우선 빠르니까 파일 처리와 텍스트 변환이 UI 를 안 막아. 그리고 안전하니까 네 파일을 건드리는 레이어가 메모리 버그로 파일을 망가뜨릴 일이 없어. 마지막으로 재현이 되고 테스트가 돼. 타입이 잡힌 입출력을 가진 순수 함수야말로, 절대 놀랄 일이 없어야 하는 앱 밑바닥에 딱 필요한 물건이거든. 판단 레이어는 확률적이어도 되지만 네 파일에 쓰는 레이어는 그러면 안 되고, Rust 가 그 규율을 강제해줘.

#[tauri::command]
fn apply_ruleset(doc: String, ruleset: Ruleset) -> Result<String, String> {
    // 순수 변환: 같은 doc 에 같은 ruleset 이면 항상 같은 출력.
    // 모델 호출도 무작위도 없어서 재현 가능하고 unit 테스트도 돼.
    Ok(ruleset.apply(&doc))
}

파일 IO 는 Rust 커맨드

.md 파일을 읽고 쓰는 일 자체가 결정론적 작업이라서, 프론트엔드가 직접 하지 않고 Tauri IPC 로 부르는 Rust 커맨드가 맡아. '결정론은 Rust' 라는 봉합선을 그대로 지키는 셈이고, webview 파일 API 를 쓸 때 딸려 오는 fs-scope 배관도 피할 수 있어. 프론트엔드는 Rust 코어한테 불러달라거나 저장해달라고 요청하고, 디스크를 실제로 건드리는 건 Rust 코어뿐이야. 파일 입출력의 주인이 하나뿐이라는 게 트랙 7 에서 다시 중요해져. 거기서 파일시스템을 진실의 원천으로 못 박거든.

Code

결정론적 변환을 Tauri 커맨드로·rust
// 결정론적 작업: 같은 입력이면 항상 같은 출력.
// Rust 에 살고 프론트엔드에서 Tauri IPC 로 부르지.
#[tauri::command]
fn apply_ruleset(doc: String, ruleset: Ruleset) -> Result<String, String> {
    // 모델도 무작위도 없는, 순수하고 unit 테스트 가능한 변환.
    Ok(ruleset.apply(&doc))
}

#[tauri::command]
fn read_note(path: String) -> Result<String, String> {
    std::fs::read_to_string(&path).map_err(|e| e.to_string())
}

#[tauri::command]
fn write_note(path: String, contents: String) -> Result<(), String> {
    std::fs::write(&path, contents).map_err(|e| e.to_string())
}

External links

Exercise

결정론적 변환을 하나 골라봐. '선택 영역을 shortcode 로 감싸기' 나 'frontmatter 제거하기' 같은 것. 타입 시그니처를 써봐. 뭐가 들어가고 뭐가 나오는지. 그다음 그게 맞다는 걸 증명할 한 줄짜리 unit 테스트를 써. '이걸 더 따뜻하게' 같은 판단 작업으로는 둘 다 깔끔하게 안 나온다는 걸 확인해. 그게 바로 그런 일이 결정론적 코어에 안 속하는 이유야.
Hint
결정론적 함수는 (doc, args) -> output 같은 시그니처가 나오고 assert(fn(input) == expected) 같은 테스트를 쓸 수 있어. '톤에 따라 달라서' expected 를 하나로 못 적겠다면, 그 작업은 결정론이 아니라 판단이야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.