절차로 구현되지 않은 연속의 예는 무엇입니까?


15

SO에 대한 콜백연속 의 차이점에 대한 흥미로운 논의 로 인해이 질문이 제기되었습니다. 정의에 따르면 연속은 계산을 완료하는 데 필요한 논리의 추상 표현입니다. 대부분의 언어에서 이것은 지속적인 처리가 필요한 값을 전달하는 하나의 인수 절차로 나타납니다.

순전히 기능적인 언어 (모든 기능이 순수하고 일류 시민 인 경우)에서 연속은 전체적으로 함수로 모델링 될 수 있다고 생각합니다. 결국 이것은 내가 지금까지의 연속을 이해 한 방법입니다. 그러나 세계는 상태로 가득 차 있기 때문에 일반적인 정의에는 연속 캡처 프로그램 상태가 필요하지 않습니다. 의도 만 포함하면됩니다.

이해를 돕기 위해 함수보다 연속성이 더 추상적 인 방식으로 표현되는 함수형 언어로 예제를 제공 할 수 있습니까? Scheme을 사용하면 현재 연속을 일류 방식 (call / cc)으로 잡을 수 있지만 call / cc에 전달 된 하나의 인수 절차에는 단순히 다른 연속의 형태로 현재 연속이 주어진 것처럼 보입니다. 호출 / cc'd 함수가 결과를 적용 할 수있는 인수 프로 시저


아마도 연속성과 기능 해제의 교차점은 다음과 같습니다. 연속은 기능 해제를 통해 데이터 구조로 변환 될 수 있습니다. 살펴볼 흥미로운 영역이 될 수 있습니다.
Dan D.

@DanD. 내가 읽을 수있는 흥미로운 문헌에 대한 제안이 있습니까? 그 주제는 유용하게 들립니다.
David Cowden

답변:


11

tl; dr; 유형의 연속을 통해 무엇보다 중요한 추상화


연속은 입력 및 출력 유형입니다.

비프로 시저 기반 연속에 가장 가까운 것은 Haskell연속 모나드 가 유형으로 표현되기 때문에 많은 함수가 유형과 상호 작용하여 인터럽트, 재개, 역 추적 등을 수행하는 데 사용될 수 있습니다.

Cont모나드 추상화를 "상위 추상화"로 얻는 하스켈 의 타입과 같은 타입으로 클로저를 캡슐화 할 수 있으며, 연속체를 타입 대신에 타입 으로 볼 때 얻는 연속체에 대한 다른 형태의 추상화 가 있습니다. 단순히 절차 , 예를 들어

  • 유형이 법에 따라 단일체 가되는 경우 두 가지 연속을 사용하고 둘 사이의 대안을 수행 할 수 있습니다.
  • 클로저를 functor 의 법칙에 위배되는 유형으로 캡슐화하면 유형에 대해 추상화하여 연속의 입력 또는 출력 유형을 변경할 수 있습니다.
  • 응용 함수 의 법칙을 따르는 유형으로 클로저를 캡슐화하는 경우 입력 유효성 검사 또는 입력 변환과 같은 기능을 사용하여 연속을 임의로 부분적으로 적용하거나 꾸밀 수 있습니다.

폐쇄 대 절차

하루가 끝나면 기본적으로 맞습니다. 연속은 "프로 시저"이지만, 오히려 폐쇄라고합니다. 종종 연속은 바운드 환경을 포함하는 일류 폐쇄로 가장 잘 표현됩니다. 순수한 기능적 언어에서는 참조가 없기 때문에 이것이 합리적이지 않다고 말할 수 있습니다. 이것은 사실이지만 값을 묶을 수 있고 단일 할당은 값과 참조를 묶는 것과 똑같은 것을 만듭니다. 이것은 Haskell에서 발생합니다.

(\x -> \y -> insideYIcanAccess x (and y))

기술적으로 최고 수준의 클로저를 부족할 수 바인딩 환경을 묶어야 할 수있는 능력이 부족하지만, 그렇다하더라도이 인 언어 일부 폐쇄 사용할 수 있습니다 환경 (일반적으로 전역).

따라서 연속을 다음과 같이 설명하는 것이 더 정확하다고 말합니다 . 특정 방식으로 사용되는 클로저.


결론

의 질문에 "절차 이외의 방법으로 연속 구현 가능한인가?" 아니요. 퍼스트 클래스 함수 가없는 경우 실제로 계속할 수 없습니다 (예 : 함수 포인터는 퍼스트 클래스 함수로 계산되므로 임의의 메모리 액세스로 충분할 수 있음).

지금의 질문에 "절차보다 더 추상적 인 방법으로 계속을 표현하는 어떤 방법이 있습니까?" 유형으로 표현하면 더 큰 추상화를 제공하여 연속을 매우 일반적인 방식으로 처리하여 연속을 실행하는 것보다 더 많은 방식으로 연속과 상호 작용할 수 있습니다.


1
"연속은 단순히 나머지 프로그램의 결과를 얻을 수있는 어떤 것도 될 수 있습니다"로 일반화됩니다. 이것은 일반적으로 일부 코드 (프로그램의 나머지 부분)를 가지고 있기 때문에 대부분의 언어는 함수를 사용합니다. 이론적으로는 무엇이든 연속체를 만들 수 있습니다. 컴파일러에서 연속 변환 중에 부분적으로 채워진 트리를 사용했습니다.
Daniel Gratzer

1
@jozefg 부분적으로 채워진 트리는 계산으로 표현을 올바르게 표현한 것이지만, 하루가 끝날 때 실제 코드는 이해하는 것처럼 프로 시저와 식별 할 수없는 종류의 표현입니다. 그 옆에 부분적으로 채워진 트리가 컴파일러 표현입니다. 개발자 표현은 예상대로 언어의 구문과 의미를 가진 계산 표현이며, 이는 개발자의 99 %에게 "프로 시저", "함수"또는 기타로 나타납니다. 당신은 컴파일러 개발자의 관점에서 생각하고 있습니다
Jimmy Hoffa

2

당신이 좋아할만한 한 가지 예는 코 루틴입니다. 예를 들어 Lua의 Coroutines 또는 Python 또는 C #의 반복자 / 생성기는 일회성 연속 (한 번만 호출 할 수있는 연속)과 유사하지만 연속이 명시 적으로 함수로 만들어지지는 않습니다. 대신, 다음 "수율"진술 문까지 코 루틴을 발전시킬 방법이 있습니다.

예를 들어 다음 Python 프로그램을 고려하십시오.

def my_iterator():
   yield 1
   yield 2
   yield 3

def main():
   it = my_iterator()
   x = it.next()
   y = it.next()
   z = it.next()
   print x + y + z

명시적인 콜백이있는 다음 Javascript 프로그램과 유사합니다.

function my_iterator()
  return function(cb1){
    cb1(1, function(cb2){
      cb2(2, function(cb3){
        cb3(3, function(cb4){
          throw "stop iteration";
        });
      });
    });
  });
}

function main(){
   var getNext1 = my_iterator();
   getNext1(function(x, getNext2){
      getNext2(function(y, getNext3){
         getNext3(function(z, getNext4){
            console.log(x + y + z);
         });
      });
   });
}

자바 스크립트 예제는 각 단계가 다음 연속을 반환해야 할뿐만 아니라 산출 된 값을 반환해야하기 때문에 시끄 럽습니다. (파이썬에서 사이트 내부의 연속을 추적합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.