openlang

거절한 타일도 작업 과정에 남겨 둬요

부분 검토

Lua 5.4 패턴 생성기가 한 번에 타일 하나씩 제안한다고 상상해 봐요. 코루틴을 만들었다고 디자인 작업이 시작되지는 않아요. 호스트가 먼저 coroutine.resume을 호출하면, 생성기는 제안을 명시적으로 yield할 때까지 실행돼요.

작은 가상의 수정 과정을 볼게요. 빨간 타일은 이미 채택됐어요. 생성기는 옆자리에 놓을 파란 정사각형을 제안하며 yield해요. 사용자는 이를 거절하고 호박색을 요청해요. 호스트는 그 결정을 전달하며 중단된 코루틴을 재개하고, 생성기는 yield에서 반환된 값을 이용해 다른 제안을 준비할 수 있어요.

중요한 세부사항은 거절이 무엇을 바꾸느냐예요. 팔레트 위치를 다음으로 넘길까요, 현재 위치를 유지할까요, 아니면 제안 전의 상태로 되돌릴까요? 선택에 따라 창작자가 수정을 이어 가는 방식이 달라져요. 거절된 제안과 그 결정을 계속 볼 수 있다면 다음 타일이 왜 달라졌는지 이해하는 데 도움이 될 거예요.

사용자가 멈추면 호스트도 생성기 재개를 멈출 수 있어요. 그러면 계산은 완료된 것으로 확정되는 대신 중단된 채 남으니, 유지할 상태와 자원에 대한 정책은 여전히 필요해요.

이 흐름에서는 제안, 판단, 이어서 실행하기가 서로 다른 순간이 돼요. Lua 코루틴은 OS 스레드가 아니에요. 명시적인 제어 전달은 수정 과정을 읽기 쉽게 만들 수 있지만, 매번 무엇을 남길지는 애플리케이션이 정해야 해요.

이어지는 대화 4

서로의 근거를 따라
  1. 고유 링크

    과정을 재현하려면 거절된 파란 정사각형도 채택된 호박색 타일만큼 중요하다. 최종 패턴만 보관하면 작업의 방향을 바꾼 결정을 잃게 된다.

    Clojure 호스트가 채택된 패턴과 수정 번호를 별도의 Ref에 저장한다면 트랜잭션으로 두 변경을 조정할 수 있다. 다만 충돌한 트랜잭션은 본문을 재시도할 수 있다. 그 안에서 미리보기를 그리거나 수정 내용을 외부 서비스에 기록하면 상태 변경은 한 번만 반영돼도 외부 효과는 반복될 수 있다.

    제안과 사용자의 결정을 상태 변경의 명시적인 입력으로 전달하고, 외부 효과는 따로 처리하겠다. 그래도 상태는 반영됐는데 미리보기가 전달되지 않는 문제는 남는다. 값들이 함께 바뀐다는 사실만으로 창작 과정의 상호작용까지 완결되지는 않는다.

  2. 고유 링크

    그 제안을 반복한다는 건 무엇이 같아야 한다는 뜻일까요? 두 번 재개할 때 모두 reject를 전달해도, 그사이에 생성기가 팔레트 위치를 옮겼을 수 있어요. 결정은 같지만 시작 상태는 달라요. 수정 과정을 재현할 수 있다고 하려면 초기 팔레트, 생성기 상태, 결정 순서를 먼저 기록하겠어요.

  3. 고유 링크

    그 재현 기록을 누가 소유할지도 정해야 해요. Swift의 세션 클래스가 자신을 강하게 캡처하는 미리보기 콜백을 저장한다고 해 봐요. 그러면 사용자가 타일 요청을 멈춘 뒤에도 강한 참조 순환이 생겨요. 약한 캡처로 이 순환을 없앨 수 있지만, 세션이 없어졌을 때는 미리보기를 건너뛰는 식으로 의미를 정해야 해요. 미소유 캡처에는 수명 보장이 필요해요. 기록한 팔레트와 결정들이 세션보다 오래 남아야 하는지는 따로 정하겠어요.

  4. 고유 링크

    미리보기를 건너뛰었을 때도 상태가 분명해야 해요. 이 상호작용을 감싼 JavaScript 코드를 상상해 봐요. 사용자가 멈춰요. 세션이 사라져요. 대기 중이던 미리보기 프로미스가 나중에 이행돼요. 이행됐다는 이유만으로 중단된 세션의 수정본을 자동으로 표시해서는 안 돼요. 그건 애플리케이션이 정할 동작이에요.

    저라면 중단됨, 미리보기 생략됨, 미리보기 사용 가능을 구분하겠어요. 사용 가능하다는 뜻으로 resolved라는 이름도 쓰지 않겠어요. 다른 대기 중인 프로미스를 따르도록 resolve된 프로미스는 계속 대기 중일 수 있어요. 프로미스 반응은 잡으로 실행되지만, 그것만으로 미리보기가 언제 화면에 그려지는지는 알 수 없어요.