벽한 위의 예에는"실제"용도의 연속 작업
-
09-06-2019 - |
문제
하려고 해요 개념을 파악의 연속 작업과 여러 개의 작은 교육 예는 다음과 같은 이 중 하나에서 위키 문서:
(define the-continuation #f)
(define (test)
(let ((i 0))
; call/cc calls its first function argument, passing
; a continuation variable representing this point in
; the program as the argument to that function.
;
; In this case, the function argument assigns that
; continuation to the variable the-continuation.
;
(call/cc (lambda (k) (set! the-continuation k)))
;
; The next time the-continuation is called, we start here.
(set! i (+ i 1))
i))
내가 이해하는 것이 작은 기능 않지만,나는 볼 수 없습니다 분명한 응용 프로그램입니다.는 동안 난 기대하지 않을 사용하여 연속 작업을 통해 모든 내 코드는 곧 언제든지,원스톱 서비스가 바로 몇 가지 경우를 수 있습니다 그들은 적절할 수 있습니다.
그래서 내가 찾는 것이 더 명시 적용 코드 샘플을 것이의 연속 작업을 제공할 수 있는 나로 프로그래머입니다.
Cheers!
해결책
에 Algo&데이터 II 우리는 이러한 모든 배"exit"또는"return"서(긴)기능
예를 들어 BFS algorthm 을 통과하는 나무 구현되었 다음과 같다:
(define (BFS graph root-discovered node-discovered edge-discovered edge-bumped . nodes)
(define visited (make-vector (graph.order graph) #f))
(define q (queue.new))
(define exit ())
(define (BFS-tree node)
(if (node-discovered node)
(exit node))
(graph.map-edges
graph
node
(lambda (node2)
(cond ((not (vector-ref visited node2))
(when (edge-discovered node node2)
(vector-set! visited node2 #t)
(queue.enqueue! q node2)))
(else
(edge-bumped node node2)))))
(if (not (queue.empty? q))
(BFS-tree (queue.serve! q))))
(call-with-current-continuation
(lambda (my-future)
(set! exit my-future)
(cond ((null? nodes)
(graph.map-nodes
graph
(lambda (node)
(when (not (vector-ref visited node))
(vector-set! visited node #t)
(root-discovered node)
(BFS-tree node)))))
(else
(let loop-nodes
((node-list (car nodes)))
(vector-set! visited (car node-list) #t)
(root-discovered (car node-list))
(BFS-tree (car node-list))
(if (not (null? (cdr node-list)))
(loop-nodes (cdr node-list)))))))))
당신이 볼 수있는 알고리즘을 종료될 때에는 노드를 발견 true 를 반환합니다:
(if (node-discovered node)
(exit node))
는 기능을 줄 것이"반환 값이":'노드'
왜 기능을 종료하기 때문에 이 문의:
(call-with-current-continuation
(lambda (my-future)
(set! exit my-future)
때 우리가 사용하는 출구,그것은 다시 갈 것입니다 상태를 실행하기 전에,비우 호출 스택과 값을 반환을 했다.
그래서 기본적으로 전화-cc 사용(여기)을 재귀,함수를 기다리지 않고 전체 재귀를 그 자체로 끝(수있는 매우 비싼을 할 때 많이에서 전산모사의 일)
다른 작은 예와 같은 일을 호출-cc:
(define (connected? g node1 node2)
(define visited (make-vector (graph.order g) #f))
(define return ())
(define (connected-rec x y)
(if (eq? x y)
(return #t))
(vector-set! visited x #t)
(graph.map-edges g
x
(lambda (t)
(if (not (vector-ref visited t))
(connected-rec t y)))))
(call-with-current-continuation
(lambda (future)
(set! return future)
(connected-rec node1 node2)
(return #f))))
다른 팁
해변:
@Pat
해변
네 해변 좋은 예입니다.내가 열람 코드고 빠르게 이 메시지가 보여주는 통과하 제어 구성품 사이에서 겉으로는 statefull 방법으로 건너 Web.
WAComponent >> call: aComponent
"Pass control from the receiver to aComponent. The receiver will be
temporarily replaced with aComponent. Code can return from here later
on by sending #answer: to aComponent."
^ AnswerContinuation currentDo: [ :cc |
self show: aComponent onAnswer: cc.
WARenderNotification raiseSignal ]
너무 좋다!
내가 내 자신의 단위 테스트용 소프트웨어입니다.실행하기 전에 테스트를 저장합 연속 실행하기 전에 테스트,그리고 다음에 실패,I(선택적으로)말획의 통역을 드롭으로 디버깅 모드와 다시 호출을 지정합니다.이 수 있는 방법을 통해 단계별 문제가 되는 코드는 정말 쉽습니다.
하는 경우 연속 작업은 직렬화,저장할 수 있습니다 또한 다음에 실패 응용 프로그램,그리고 다시 호출에 그들에 대한 자세한 정보를 얻을 수있는 변수 값,스택 추적이,등등.
연속 작업에 의해 사용되는 웹 서버 및 웹 프레임워크 세션 정보를 저장하.연속체를 위해 만든 각 세션 및 그에 의해 사용되는 각 요청에 있습니다.
나는 전체의 구현 amb
연산자 이 게시물 서 http://www.randomhacks.net, 를 사용하여,연속.
여기에 무엇인 amb
opeerator 않:
# amb will (appear to) choose values
# for x and y that prevent future
# trouble.
x = amb 1, 2, 3
y = amb 4, 5, 6
# Ooops! If x*y isn't 8, amb would
# get angry. You wouldn't like
# amb when it's angry.
amb if x*y != 8
# Sure enough, x is 2 and y is 4.
puts x, y
그리고 여기에 게시물의 구현:
# A list of places we can "rewind" to
# if we encounter amb with no
# arguments.
$backtrack_points = []
# Rewind to our most recent backtrack
# point.
def backtrack
if $backtrack_points.empty?
raise "Can't backtrack"
else
$backtrack_points.pop.call
end
end
# Recursive implementation of the
# amb operator.
def amb *choices
# Fail if we have no arguments.
backtrack if choices.empty?
callcc {|cc|
# cc contains the "current
# continuation". When called,
# it will make the program
# rewind to the end of this block.
$backtrack_points.push cc
# Return our first argument.
return choices[0]
}
# We only get here if we backtrack
# using the stored value of cc,
# above. We call amb recursively
# with the arguments we didn't use.
amb *choices[1...choices.length]
end
# Backtracking beyond a call to cut
# is strictly forbidden.
def cut
$backtrack_points = []
end
나 amb
!
연속 작업에서 사용할 수 있"실제"예할 때마다 프로그램 교류는 선형이 아니거나 심지어 미리 결정된다.는 친숙한 상황이 웹 응용 프로그램.
연속 작업에 좋은 스레드당에서 요청을 서버 프로그래밍(를 포함하여 웹 응용 프로그램을 지원하는 프런트 엔드.
이 모델에서 대신,새로운 발사(무거운)스레드가 모든 요청에서,당신은 단지 시작에서 몇 가지 작업을하는 기능입니다.그 후,당신이 준비 되어 있을 때에 차단 I/O(i.e에서 읽은 데이터베이스)전달 연속으로 네트워킹 응답 처리기입니다.경우 응답이 돌아온다는 실행,지정합니다.이 계획,프로세스할 수 있습을 많이 가진 요청은 단지 몇 스레드입니다.
이것은 제어 흐름보다 더 복잡을 사용하여 스레드를 차단하지만,부하가,그것은 더 효율적으로(적어도에서 오늘날의 하드웨어).
Amb 연산자입니다 좋은 예를 할 수 있는 프롤로그 같은 선언적 프로그래밍입니다.
우리가 말하는 내가 코딩 음악의 조각 구성 소프트웨어에서 방식(음악으로 다음을 지식의 이론 음악 및 분석 내 자신의 조각을 볼 수학의 뒤에 그것을 작동합니다.)
를 사용하 amb 운영자가 입력 제약 조건이 멜로디를 만족해야한다고 체계 그 밖의 결과입니다.
연속 작업은 아마에 넣고 계획하기 때문에 언어 철학,계획하는 프레임워크 활성화를 실현하기 위해 당신에 대해 어떤 프로그래밍 패러다임을 발견에서 다른 언어에 의해 정의하는 라이브러리에서 제도 자체입니다.연속 작업을 수 있을 만들기 위한 당신의 자신의 추상적인 통제 구조물은'수익','깨 또는 사용하는 선언적 프로그래밍입니다.방식은 더 많은'일반화'엽기적인 그런 생성 할 수 있어야에 의해 지정된 프로그래머 too.
는 방법에 대 Google Mapplets API?무리가 있의 기능을(모든 종료에 Async
용)는 당신이 통과 콜백입니다.API 함수가 비동기 요청의 결과,그 다음 전달하는 결과를 콜백(으로"다음에 할 것이").소리를 많이 좋아 연속 전달하는 스타일 다.
이 예 여 매우 간단하는 경우.
map.getZoomAsync(function(zoom) {
alert("Current zoom level is " + zoom); // this is the continuation
});
alert("This might happen before or after you see the zoom level message");
이것으로 자바스크립트가 없 리 호출 최적화, 다,그래서 스택과 함께 성장할 것입니다 모든 전화로 계속,당신은 결국 돌아가 실의 제어하는 브라우저입니다.모두 같은 생각,그것의 좋은 추상화입니다.
이 있는 경우 호출하는 비동기 작업 일시 중지될 때까지 실행 당신은 결과를 얻을,당신은 일반적으로 어느 설문 조사 결과에 대한 두거나 나머지 부분의 코드에서 콜백에 의해 실행되는 비동기 조치에 따라 완료합니다.으로 연속 작업을 할 필요가 없는 비효율적인 옵션의 폴링,당신은 필요하지 않 포장의 모든 당신의 코드를 실행한 후 asynch 이벤트 콜백에서-그냥 통과하는의 현재 상태 코드로 당신의 콜백 및 코드가 효과적으로"깨어"로 asynch 작업이 완료됩니다.
연속 작업을 구현하는 데 사용할 수 있는 예외를 제외하고,디버거.