명명 된 let을 사용하여 Scheme에 루프를 작성하려고합니다. 끝 부분에서 항상 반복하는 것이 아니라 다양한 기준에 따라 반복을 빠져 나가고 싶습니다. 효과적으로 while
, break
및 continue
을 갖고 싶습니다. 나는 강한 이유 때문에 guile 1.8을 사용하도록 제한되었고, guile 1.8은 R6RS while
구조를 구현하지 않습니다. 내 질문은 꼬리 재귀 있어야 이름을 사용하여 recursing 않는, 왜 끝날 전에 루프를 다시 시작할 수 없습니다? [코드 예제가 필요합니까?] IO 작업과 함께 여러 지점에서 초기 종료를 사용하여 재귀하려고하면 필연적으로 과거 EOF를 읽고 예측할 수없는 데이터 손상이 발생합니다.Scheme에서 명명 된 let
0
A
답변
2
(let name ((iter iter-expr) (arg1 expr1) (arg2 expr2))
(cond
(continue-predicate (name (next iter) arg1 arg2)))
(break-predicate break-expression-value)
(else (name (next iter) next-arg1-expression next-ar2-expression))))
A는 바로 다음 일은 변경 될 것이다 반복 부분을 제외하고 변경되지 않은 같은 인수의 대부분을 사용하여 다시 호출 계속합니다.
휴식은 기본 사례입니다.
그럼 while
은 무엇입니까? 이는 구분 술어와 기본 대소 문자가있는 let
입니다.
스키마에는 실제로 while
구조가 없습니다. 보고서를 읽는다면 그 보고서는 단지 설탕 (매크로)이라는 것일 뿐이며 let
과 같은 것으로 변합니다.
수행 할 이전 계산을 모두 수행하지 않고 종료 할 수 있도록하려면 꼬리 재귀가되어야합니다. call/cc
을 사용하여 기본적으로 Scheme이 후드 아래에있는 출구 연속을 제공 할 수도 있습니다. 일반적으로 call/cc
는 초보자를위한 아주 멀리이며 꼬리 재귀 이런 일을보다 이해하기 쉽게 당신의 절차를 만들기 때문에 마스터 시간이 좀 걸립니다 :
(define (cars lists-of-pair)
(call/cc (lambda (exit)
(fold (lambda (e a)
(if (pair? e)
(cons (car e) a)
(exit '()))) ; throw away continuations to make current result make it()
'()
lists-of-pair)))
(cars '((1 2) (a b))) ; ==> (1 a)
(cars '((1 2)())) ; ==>()
당신이 지금까지 시도했습니다 것을 보여주기 위해 유용 할 것이다 . 'while', 'break'및 'continue'에 대해 언급합니다. 즉, 명령형 (C-style)을 비 명령형 언어로 가져 오는 것처럼 소리를 내며, 따라서 극도로 독창적 인 방식을 쓰려고합니다. –
(특정 질문에 대해서는 아니오, 재귀 호출은 꼬리 호출이 아니어도 상관 없습니다. 예, 어느 시점에서든 '루프'를 다시 시작할 수 있으며 예, 코드 예제가 도움이됩니다) –
가이아 2가 적합하다고 보는 것 외에는 while 구조를 새로운 기능으로 통합 할 수 있습니다. 내 맥락은 실제로 가일입니다. Guile은 실제로 C/C++ 코드와의 통합을위한 것이며 이러한 종류의 명령형 작업은 시간이 지나면 발생합니다. 우리는 여기서 '순수한'계획을 말하지 않고있다. – andro