일류 연속체가 현대 객체 지향 프로그래밍 언어에 유용합니까?


10

연속은 함수형 프로그래밍 언어 (예 : ContHaskell 의 모나드)에서 매우 유용 합니다. 명령형 코드에 대해 단순하고 규칙적인 표기법을 허용하기 때문입니다. 또한 누락 된 언어 기능 (예 : 예외, 코 루틴, 녹색 스레드)을 구현하는 데 사용할 수 있기 때문에 일부 오래된 명령형 언어에서도 유용합니다. 그러나 이러한 기능을 내장 지원하는 현대적인 객체 지향 언어에 대한도 (여부 현대 컬럼 식별자 스타일 일류 연속 요청에 대한 지원을 추가하기위한 어떤 인자가있을 것입니다 resetshift또는 계획 같은 call-with-current-continuation)?

성능 및 구현 복잡성 이외의 지원 추가 에 반대 하는 주장이 있습니까?

답변:


15

Eric Lippert가이 질문에 대답하도록하겠습니다.

이 시점에서 분명한 질문은 CPS가 너무 훌륭하다면 항상 사용하지 않는 것입니다. 왜 대부분의 전문 개발자가 그것을 들어 본 적이 없거나, 그것을 가진 사람들은 그것을 미친 Scheme 프로그래머 만이하는 것으로 생각합니까?

우선, 서브 루틴, 루프, try-catch-finally 등을 생각하는 데 익숙한 대부분의 사람들은 이러한 방식으로 제어 흐름에 델리게이트가 사용되는 것에 대해 추론하기가 어렵습니다. CS442의 CPS에 대한 메모를 지금 검토 중이며 1995 년에 profQUOTE를 썼다는 것을 알 수 있습니다.“계속하려면 머리에 서서 안으로 몸을 내 밀어야합니다.” Duggan 교수 (*)는 그 말에 절대적으로 맞았습니다. 며칠 전 C # 식 M (B ()? C () : D ())의 CPS 변환에 대한 작은 예제에는 4 개의 람다가 포함되어있었습니다. 모든 사람이 고차 함수를 사용하는 코드를 읽는 데 능숙하지는 않습니다. 그것은 큰인지 부담을 부과합니다.

또한, 특정 제어 흐름 문을 언어로 구워낸 것에 대한 좋은 점 중 하나는 코드가 메커니즘을 숨기면서 제어 흐름의 의미를 명확하게 표현할 수 있다는 것입니다. 호출 스택 및 반환 주소와 예외 처리기 목록 및 보호 된 영역 등등. 계속하면 코드 구조에서 제어 흐름 메커니즘이 명확 해집니다. 메커니즘에 중점을 둔 것은 코드 의 의미 를 압도 할 수 있습니다 .

에서 다음 기사 그는 비동기 및 연속 요청이 서로 정확히 동일 방법을 설명하고, 모든 숨겨진 다루 확인하고, 간단한을 복용 (그러나 차단) 동기 네트워크 운영 및 asyncronous 스타일로 다시 작성의 데모를 넘어 제대로하기 위해서는 반드시 다루어야 할 문제가 있습니다. 엄청난 코드 혼란 으로 바뀝니다 . 마지막에 그의 요약 :

신의 선하심, 우리가 만든 엄청난 혼란. 우리는 두 줄의 완벽하게 명확한 코드를 당신이 이제까지 본 것 중 가장 맛있는 스파게티의 두 줄로 확장했습니다. 물론 레이블이 범위 내에 있지 않고 명확한 할당 오류가 있기 때문에 여전히 컴파일되지 않습니다. 우리는 여전히 이러한 문제를 해결하기 위해 코드를 다시 작성해야합니다.

CPS의 장단점에 대해 내가 말한 것을 기억하십니까?

  • PRO : 간단한 부품으로 임의로 복잡하고 흥미로운 제어 흐름을 구축 할 수 있습니다.
  • CON : 연속을 통한 제어 흐름의 확인은 읽기 어렵고 추론하기가 어렵습니다.
  • CON : 제어 흐름의 메커니즘을 나타내는 코드가 코드의 의미를 완전히 압도합니다.
  • 단점 : 일반적인 코드 제어 흐름을 CPS로 변환하는 것은 컴파일러가 능숙한 종류이며 다른 사람은 거의 없습니다.

이것은 지적 운동이 아닙니다. 실제 사람들은 비동기를 처리 할 때 항상 위와 동등한 코드를 작성합니다. 그리고 아이러니하게도 프로세서가 더 빠르고 저렴 해지더라도 우리 는 프로세서에 얽매이지 않은 것들을 기다리는 데 점점 더 많은 시간을 소비 합니다. 많은 프로그램에서 많은 시간을 소비 한 시간은 프로세서가 네트워크 패킷이 영국에서 일본으로 이동하여 다시 돌아올 때까지 기다리거나 디스크가 돌아가는 등 무엇이든 기다리지 않는 것입니다.

그리고 비동기 작업을 더 구성하려면 어떻게되는지에 대해서는 이야기하지 않았습니다. ArchiveDocuments를 대리자를받는 비동기 작업으로 만들고 싶다고 가정합니다. 이제이를 호출하는 모든 코드는 CPS로 작성되어야합니다. 오염이 막 퍼집니다.

비동기 로직 권리를 얻는 것은 중요합니다, 그것은 단지가 될 것 미래에 더 중요한, 우리가 제공 한 도구를 사용하면 당신이 만드는 "당신의 머리에 서 밖으로 내 자신을 설정" 으로 교수 듀건은 현명했다.

계속되는 통과 스타일은 강력하지만, 위의 코드보다 그 힘을 잘 활용하는 더 좋은 방법이 있어야합니다.

이 모든 혼란을 컴파일러로 옮기고 특정 부분을 비동기로 표시하는 특수 키워드를 사용하여 코드를 일반 제어 흐름으로 작성할 수있는 새로운 C # 언어 기능에 관한 기사와 다음 시리즈는 다음과 같은 경우에도 읽을 가치가 있습니다. C # 개발자가 아닙니다. 나는 아니지만 처음으로 그것을 만났을 때 여전히 계몽의 경험이었습니다.


5
언어가 매크로와 같은 구문 확장을 지원하는 경우 구문 확장 내에 다양한 종류의 흥미로운 제어 흐름을 구현하기위한 메커니즘을 숨길 수 있기 때문에 연속성이 훨씬 더 유용하다는 점에 주목할 가치가 있습니다. 기본적으로 "await"의 작동 방식은 C #에서 이러한 종류의 구문 확장을 직접 정의 할 수있는 도구를 제공하지 않기 때문에 언어로 정의 된 것입니다.
Jack

CPS와 일류 연속체가 정확히 같은 것은 아니라는 점을 잘 알고 있지만, CPS는 필요할 때 연속체를 지원하지 않는 언어로 수행하는 작업입니다. C #이 내가 생각하는 것과 똑같은 경로로 내려 가고있는 것처럼 들립니다 (타이어를 CPS로 자동화하거나 전체 스택 스택 복사로 구분 된 연속을 구현할지 여부를 결정할 수는 없지만).
Jules

@Jack-바로 지금 내가 생각하고있는 것입니다. 제가 디자인하는 언어에는 CPS 변환을 자동으로 지원할 수있는 매크로 기능이 있습니다. 그러나 완전한 기본 연속 기능을 사용하면 성능이 향상 될 수 있습니다. 문제는 성능이 중요한 상황에서 얼마나 자주 사용됩니까?
Jules
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.