openlang

eval이 호스트 전역 변수로 넘어가도 될까요?

env에서 rate를 3으로 묶어 두면 eval("rate + 1", env)는 4여야 해요. 컴파일 타임 모드에서도, 런타임 모드에서도, 언제나요. 호스트 쪽 가변 전역 변수 rate를 9로 바꿔도 이 입력의 의미는 그대로여야 하고요.

이 실험용 D 평가기에서 원하는 규칙이 이거예요. 그러려면 환경은 항상 인자로 받아야 해요. 첫 예제는 전역 조회를 쓰는 쪽이 더 짧겠지만요. D도 이미 이쪽으로 기울어 있어요. 컴파일 타임 값이 필요한 곳에서 해당 함수를 평가하고, CTFE 코드는 가변 전역이나 static 변수를 참조하지 못해요. 좋은 압력 시험이에요. 그런데 생각보다 좁은 약속이네요. 모든 함수가 CTFE로 돌아가는 것도 아니고, CTFE가 범용 보안 샌드박스인 것도 아니에요.

비용은 호스트가 져요. 평가기에 보여 줄 바인딩을 전부 직접 모아서 넘겨야 하니까요. 대신 같은 식과 같은 환경이면 두 모드에서 의미가 같아져요.

rate가 없으면 호스트 전역으로 슬쩍 넘어가는 일은 없어요. 거부예요. 런타임 복구 장치는 나중에 붙일 수 있는데, 그때 문서에는 넘겨받은 대체 값이 평가 입력에 포함되는지도 적어야 해요.

이어지는 대화 3

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

    감지와 복구는 rate가 없는 바로 그 지점에서 갈라집니다. 평가기는 바인딩이 없다는 것을 압니다. 무엇으로 대신할지는 모릅니다. 호스트는 알 수도 있습니다.

    Common Lisp은 이 두 일을 나누어 둡니다. 평가기는 빠진 바인딩을 명시한 조건을 신호하고, 값을 받아들이는 재시작을 설정합니다. 맥락을 가진 호스트가 설정한 handler-bind 핸들러가 그 재시작을 호출할 수 있습니다. 핸들러가 그냥 반환하면 처리를 맡지 않은 것이고, 그 경우 평가가 어떻게 이어지는지는 프로토콜이 밝혀야 합니다.

    이것은 가능한 런타임 인터페이스 하나이며, 대체 값은 추가 입력으로 기록되어야 합니다. 컴파일 타임 모드에는 아예 없어도 됩니다. D 실험에 적용하면 문서화할 동작이 두 가지가 됩니다. 컴파일 타임의 거부, 그리고 런타임이 제공하는 복구입니다. 어느 쪽도 호스트 전역 변수를 읽지 않습니다.

같은 질문의 다른 갈래

  1. 시계를 읽는 규칙은 어떻게 재현하나요?

    moth의 D 질문에서는 rate가 주어진 환경으로 들어왔어요. 런타임 규칙은 입력을 더 조용히 숨길 수 있어요. 여기서는 eligible(item)이 호스트 시계와 그 순간 최신인 카탈로그 리비전을 읽어요. 둘 다 넘겨주면…