본문 바로가기
C.W.K.
Stream
Lesson 01 of 05 · published

뜻한 순간과 벌어지는 순간 사이

~12 min · async-gap, intent-vs-effect, boundary, core-problem

Level 0식은 부싯돌
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"자리는 완벽하게 붙잡았어. 그리고 기다렸지. 그 기다림이 모든 게 틀어질 수 있는 자리야."

깔끔했던 붙잡기, 그 끝

Track 3 은 자리 붙잡기를 다 끝난 일처럼 보여줬지. 포커스된 요소 읽고, 긁어놓은 글 읽고, 범위 읽고, 끝. 깔끔했어. 그런데 그 붙잡기는 전부 치는 순간 에 일어나고, 그다음 Flint 는 머리가 생각하기를 기다려야 해. 추론엔 진짜 시간이 들고 흔히 몇 초씩 걸리지. 그러니까 그 깔끔한 사진은, 넣을 답을 손에 쥐었을 즈음엔 이미 지나간 순간의 사진이야. 붙잡기의 끝이 정확히 여기 있어. 뜻했을 때의 진실은 알려줬지만, 넣을 때에 대해선 아무 말도 안 해주거든.

기다리는 동안 벌어지는 일

기다림은 죽은 시간이 아니야. 그 사이에도 사용자 세상은 계속 움직여. 다른 창을 흘끗 보다 포커스가 흘러가고, 클릭하면 긁어놓은 게 풀리고, 알림이 포커스를 뺏고, 탭을 닫거나 앱을 아예 갈아타기도 하지. 긁어놨던 글이 딴 데서 고쳐지기도 하고. 이 중 뭐 하나만 일어나도 붙잡아둔 사진이 낡아버려. 붙잡았던 앱이나 요소나 글이 더는 커서 앞에 있는 게 아니게 되는 거야. 그리고 Flint 는 글을 대신할 참이라, 낡은 사진대로 움직이면 엉뚱한 데 넣는 정도가 아니라 엉뚱한 내용을 되돌릴 수 없게 덮어쓸 수도 있어.

t0  침       붙잡기 { 앱, pid, 요소, 긁은 글, 범위 }
        |
        |   <-- 벌어진 시간: 추론이 돈다 (몇 초).
        |       포커스가 흘러가거나 / 긁힌 게 바뀌거나 /
        |       창이 닫히거나 / 앱이 갈아타거나.
        |
 t1  답     바뀐 글이 준비됨
        |
        v   넣기 전에: 그 사진이 아직 맞나?
            맞으면   -> 붙잡아둔 그 자리를 정확히 대신한다
            아니면   -> 확인 못 한 자리는 안 건드린다. 클립보드로.

사진은 사실이 아니라 주장이야

그러니까 생각을 이렇게 바꿔야 해. Flint 가 찍어둔 사진은 그대로 믿고 움직일 사실이 아니라, 한때 맞았고 다시 믿기 전에 확인해야 하는 주장 이야. 붙잡아둔 자리는 '사용자가 뜻한 것' 으로 두고, 넣을 때의 세상은 그 말에 아직 동의할 수도 아닐 수도 있는 별개의 것으로 두는 거지. 삽입이 하는 일 전부가 그 둘을 맞춰보고 맞을 때만 움직이는 거야. 그래서 붙잡기가 아니라 삽입이 제일 위험한 층인 거고. 붙잡기는 읽기만 하지만 삽입은 쓰거든. 그것도 진실이 만료될 수 있는 시간을 건너서.

뜻한 때와 벌어지는 때 사이가 벌어지는 일은 벌어지는 시점에 자리를 다시 확인해야 해. 이게 이 트랙 전체를 관통하는 법칙이야. 예약 발송, 미뤄둔 쓰기, 시간차 두고 바꿔치기. 전부 뜻을 붙잡아뒀다가 나중에 움직이고, 그 사이에 세상이 바뀔 수 있지. 벌어지는 시점에 찾은 자리에 대고 움직이는 게 버그고, 뜻했을 때 붙잡아둔 자리에 묶어두되 그게 아직 유효한지 다시 확인하는 게 고침이야. 뜻은 붙잡아두고, 벌어질 때 확인하고.
Flint 는 그냥 넣는 것보다 판돈이 커. 그게 이 트랙 나머지를 결정해. 받아쓰기 앱은 커서 자리에 글을 넣지만, Flint 는 긁어놓은 걸 대신해. 사진이 낡았을 때 그냥 넣는 쪽은 엉뚱한 자리에 떨어지는 정도지만(짜증나도 되돌릴 수 있어), 대신하는 쪽은 지금 긁혀 있는 게 뭐든 덮어쓸 수 있거든. 그 추가된 위험 때문에 다음 레슨들이 '어느 앱이 앞에 있나' 보다 훨씬 빡센 확인 — 범위까지 맞추기, 다시 복사해서 대조하기 — 을 요구하는 거야.

Code

확인하고 넣는 흐름, 한 덩이로·swift
func place(_ result: String, into snapshot: TargetSnapshot) {
    // 사진은 칠 때 맞았다. 지금도 맞나?
    switch prove(snapshot) {
    case .stillValid(let target):
        replaceSelection(with: result, in: target)   // 붙잡아둔 그 자리에
    case .changed, .unprovable:
        copyToClipboardAndNotify(result)             // 짐작으로는 안 덮어쓴다
    }
}

// 'prove' 가 세상을 다시 읽어 사진이랑 맞춰본다. 이 트랙에서 재미있는
// 부분은 전부 그 prove 가 네이티브와 불투명한 자리에서 각각 어떻게
// 구현되는지, 그리고 확신이 안 설 때 뭘 안 하기로 하는지에 있다.

External links

Exercise

추론을 기다리는 동안 그 자리에 대해 바뀔 수 있는 걸 전부 적어봐. 그리고 각각에 대해, 커서에 그냥 넣는 도구랑 Flint 처럼 긁어놓은 걸 대신하는 도구가 같은 피해를 입는지 다른 피해를 입는지 갈라봐. 마지막으로 '벌어질 때 찾은 자리' 가 왜 '뜻했을 때 붙잡은 자리' 의 안전한 대체가 절대 될 수 없는지 한 문장으로 말해봐.
Hint
포커스가 흘러가고, 긁힌 게 풀리고, 창이 닫히고, 앱을 갈아타고, 딴 데서 글이 고쳐질 수 있어. 커서에 넣는 도구는 대개 엉뚱한 자리에 떨어지는 정도라 되돌릴 수 있고, 대신하는 도구는 지금 긁혀 있는 걸 덮어쓸 위험까지 있어서 되돌리기 어려울 수 있고. 한 문장으로 하면, 벌어질 때의 자리는 사용자가 뜻한 게 아니라 세상이 흘러간 결과라서, 거기 대고 움직이면 뜻 대신 우연을 따르는 셈이 되니까.

Progress

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

댓글 0

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

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