문제

나는 어제 Stackoverflow Dev Days Convention에 있었고 스피커 중 하나가 Python에 대해 이야기하고있었습니다. 그는 메모 화 기능을 보여 주었고, 나는 비 퓨어 기능에 사용되는 것을 막을 방법이 있는지 물었다. 그는 거절했다. 그것은 기본적으로 불가능하다고, 누군가가 그것을 할 수있는 방법을 알아낼 수 있다면 훌륭한 박사 학위 논문을 만들 것이다.

컴파일러/통역사가 재귀 적으로 해결하기가 어렵지 않기 때문에 그런 종류의 혼란을 겪었습니다. 의사 코드에서 :

function isPure(functionMetadata): boolean;
begin
   result = true;
   for each variable in functionMetadata.variablesModified
      result = result and variable.isLocalToThisFunction;
   for each dependency in functionMetadata.functionsCalled
      result = result and isPure(dependency);
end;

그것이 기본 아이디어입니다. 분명히 상호 의존적 인 기능에 대한 무한 재귀를 방지하기 위해 일종의 점검이 필요하지만 설정하기는 어렵지 않습니다.

함수 포인터를 취하는 고차 함수는 정적으로 확인할 수 없기 때문에 문제가 될 수 있지만, 원래의 질문은 컴파일러가 특정 매개 변수로 전달 될 수 있다고 컴파일러에 어떤 종류의 언어 제약 조건을 가지고 있다고 전제합니다. . 존재하는 경우 상태를 만족시키는 데 사용될 수 있습니다.

분명히 이것은 해석 된 언어보다 편집 된 언어로 더 쉬울 것입니다. 프로그램이 실행되기 전에이 모든 숫자 크런치가 수행되고 느려지지 않기 때문입니다. 그러나 실제로 불가능한 근본적인 문제는 보이지 않습니다. 평가합니다.

이 분야에서 조금 더 많은 지식을 가진 사람이 내가 무엇을 놓치고 있는지 알고 있습니까?

도움이 되었습니까?

해결책

파이썬에서는 특히 어렵습니다. 부터 anObject.aFunc 런타임에 임의로 변경 될 수 있으시면 컴파일 시간에 어떤 기능이 있는지 결정할 수 없습니다. anObject.aFunc() 전화하거나 기능이 전혀 없더라도.

다른 팁

또한 모든 시스템 호출, 모든 FFI 등에 주석을 달아야합니다.

또한 가장 작은 '누출'은 전체 코드 기반으로 누출되는 경향이 있습니다.

이론적으로 다루기 어려운 문제는 아니지만 실제로는 전체 시스템이 부서지기 쉬운 방식으로 수행하기가 매우 어렵습니다.

제쳐두고, 나는 이것이 좋은 박사 학위 논문을 만든다고 생각하지 않습니다. Haskell은 이미 IO Monad와 함께 이미 (버전) 이것을 가지고 있습니다.

그리고 나는 많은 사람들이 이것을 계속해서 '실제로'보고 있다고 확신합니다. (야생 추측) 20 년 후 우리는 이것을 가질 수 있습니다.

여기에 다른 훌륭한 답변 외에도 의사 코드는 함수가 변수를 수정하는지 여부 만 살펴 봅니다. 그러나 그것은 실제로 "순수한"의미가 아닙니다. "순수"는 일반적으로 "참조 투명"에 더 가까운 것을 의미합니다. 다시 말해, 출력은 입력에 완전히 의존합니다. 따라서 현재 시간을 읽고 결과의 요소 (또는 입력에서 읽거나 기계 상태를 읽거나 ...)를 읽는 것만 큼 간단한 것은 변수를 수정하지 않고 기능을 비 영공으로 만듭니다.

또한 변수를 수정 한 "순수한"기능을 작성할 수 있습니다.

내가 당신의 질문을 읽을 때 내 마음에 튀어 나온 첫 번째 것은 다음과 같습니다.

클래스 계층

변수가 수정되었는지 여부를 결정하려면 변수에서 호출되는 모든 단일 방법을 파기하여 변수가 돌연변이되는지 확인하는 행위가 포함됩니다. 이것은 ... 비가적인 방법을 가진 밀봉 된 유형의 경우 다소 간단합니다.

그러나 가상 방법을 고려하십시오. 모든 단일 파생 유형을 찾아 해당 방법의 모든 단일 재정의 상태가 상태를 돌연변이하지 않는지 확인해야합니다. 이를 결정하는 것은 동적 코드 생성을 허용하거나 단순히 동적 인 언어 / 프레임 워크에서는 불가능합니다 (가능하다면 매우 어렵습니다). 그 이유는 런타임에 새 유형을 생성 할 수 있기 때문에 파생 유형 세트가 고정되지 않았기 때문입니다.

C#을 예로 들어 보겠습니다. 런타임에서 파생 클래스를 생성하는 것을 막는 것은 없습니다. 정적 검증은 이러한 유형의 수정을 감지 할 수 없으므로 방법이 순수한 지 여부를 검증 할 수 없습니다.

주요 문제는 효율적으로 수행 할 것이라고 생각합니다.

D- 언어에는 순수한 기능이 있지만 직접 지정해야하므로 컴파일러는 확인해야합니다. 수동으로 지정하면 더 쉬울 것이라고 생각합니다.

주어진 기능이 일반적으로 순수한 지 여부를 결정하는 것은 주어진 프로그램이 중단 될지 여부를 결정하는 데 환원 할 수 있으며, 정지 문제는 효율적으로 해결할 수없는 종류의 문제라는 것이 잘 알려져 있습니다.

복잡성은 언어에 따라 다릅니다. 보다 역동적 인 언어의 경우 언제든지 모든 것을 재정의 할 수 있습니다. 예를 들어, TCL에서

proc myproc {a b} {
    if { $a > $b } {
        return $a
    } else {
        return $b
    }
}

그 모든 단일 조각은 언제든지 수정할 수 있습니다. 예를 들어:

  • "if"명령을 다시 작성하여 글로벌 변수를 사용하고 업데이트 할 수 있습니다.
  • 같은 줄을 따라 "반환"명령은 같은 일을 할 수 있습니다.
  • "if"가 사용될 때 if 명령에 따라 IF 명령에 대한 입력에 따라 return 명령이 재정의 된 IF 명령에 실행 추적이 될 수 있습니다.

물론, TCL은 극단적 인 경우입니다. 가장 역동적 인 언어 중 하나입니다. 즉, 함수를 입력 한 후에도 함수의 순도를 결정하기가 어려울 수 있다는 문제를 강조합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top