openlang

이 큐에 개수를 캐시하는 필드가 필요할까요?

호출자가 이 큐에 묻는 건 List.length items > 8 하나뿐이고, 그걸 계속 반복해서 물어요. 큐는 불변 OCaml 리스트 하나이고, 갱신할 때마다 새 큐를 돌려줘요. 선택지는 두 가지예요. 정확한 개수를 들고 다니거나, 기준값 질의를 내보이거나요.

(items, count)로 가면 쌍 패턴이 두 구성 요소에 이름을 붙여 주고, 그때부터 count = List.length items가 모든 갱신 뒤에도 성립해야 해요. 넣으면 하나 늘어요. 꺼내기에 성공하면 하나 줄어요. 빈 큐에서 꺼내려 하면 0으로 남아요. 두 구성 요소를 함께 받는 생성 함수도 둘의 관계를 지켜야 하고요.

기준값 쪽이 더 작아요. List.compare_length_with items 8 > 0은 호출자가 원하는 걸 그대로 말해 주고, OCaml 5.4 문서에 따르면 이 비교는 최대 주어진 횟수만큼만 반복하고 멈출 수 있어요. 지금은 개수 자체를 묻는 곳이 없어서, 굳이 저장해 둘 이유가 있는지 의심이 들어요.

이어지는 대화 4

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

    질문 자체부터 드러내 보면 어떨까요? exceedsLimit queue limit로 두고, 한도는 음수가 아니어야 한다고 정해요. 호출하는 쪽은 딱 필요한 답을 얻고, 큐는 계속 맞춰 둬야 할 두 번째 구성 요소를 갖지 않아도 돼요. 이 표현에서는 안쪽에서 List.compare_length_with가 일을 해 줘요.

    호출하는 쪽이 작업을 받을지 정하는 자리라면 결과에 WithinLimit와 OverLimit라는 이름을 붙여 분기를 읽기 쉽게 할 수도 있어요. 주변의 if가 이미 구분을 설명하고 있다면 그냥 불리언이어도 괜찮아요. 비교 하나를 감싸려고 케이스를 늘릴 필요는 없어요.

    정확한 개수가 다른 곳에서 쓸모 있어지면 캐시는 그때 넣으면 돼요. 그때는 생성과 갱신을 같은 인터페이스 뒤에 두어서, 어떤 호출자도 items나 count를 혼자 바꿔 끼우지 못하게 하고요. 지금은 이 정도면 충분하겠네요.

  2. 고유 링크

    OverLimit는 생산자에게 멈추라고 할 뿐이에요. 그다음은요? 생산자가 거기서 막힌다면 그 수를 세어 봐야 해요. 가득 찬 채널에서 멈춘 고루틴은 싸지만, 거기 몇 개까지 쌓일 수 있는지는 아무것도 막지 않아요. 큐의 한도는 대기열을 아무도 재지 않는 곳으로 옮길 뿐이에요.

  3. 고유 링크

    그 인터페이스를 .mli에 두고 type t는 정의 없이 선언만 하십시오. 그러면 모듈 밖 어디에서도 그 쌍을 손으로 만들 수 없고, 나중에 개수를 추가해도 바뀌는 파일은 하나, 불변식이 깨질 수 있는 곳도 정확히 한 군데입니다.

  4. 고유 링크

    뭘 따로 추가하지 않으면 아무것도 없어. Kotlin에서 용량이 정해진 Channel은 꽉 차면 send를 중단시키는데, 중단된 송신자도 각자 잡은 걸 다 들고 있는 살아 있는 코루틴이야. 그 수는 그냥 띄운 만큼이고. 띄우는 쪽을 제한하든가, 앞에 Semaphore를 둬.

같은 질문의 다른 갈래

  1. Fortran 열 우선 배열의 루프 순서

    Fortran 배열은 열 우선이다. a(i,j)와 a(i+1,j)는 메모리에서 이웃이다. a(i,j+1)은 열 하나만큼 떨어져 있다. 그러니 메모리를 순서대로 훑는 루프는 j가 바깥, i가 안쪽이다. C 습관대로 거꾸로 써도…

    답글 1fortran