2017-01-13 2 views
1

do 루프에서 함수에서 반환 된 여러 값을 바인딩하는 방법은 무엇입니까? 다음은 분명히 매우 잘못되었지만 가능한 일입니까?Common Lisp의 do 루프에서 여러 값을 바인드합니다.

(do (((x y z) (3-val-fn) (3-val-fn))) 
    ((equal y 'some-val) y) 
    (values x y z)) 

아니면 다중 값 바인딩을 사용하여이 작업을 수행 할 수 있습니까?

+0

이 문제는 더 심각한 문제, 즉 복수 값을 부적절하게 사용하는 것으로 나타납니다. 의미를 공유하기위한주의? – kennytilton

+0

@kennytilton 실제 코드가 아닙니다. 나는 여러 가치를 실험하고 그들에 대해 배우려고했습니다. –

+0

문제는 CL이 일을하는 데 백만 가지 방법이 있다는 것인데 실제 환경의 진공 상태에서의 질문은 본질적으로 답을 얻을 수 없기 때문입니다. 마찬가지로, LOOP가 여러 값을 소멸시키기위한 구문 적 설탕을 제공하지 않는 이유가 여기에 있습니다. 여러 값을 적절히 사용하면 절대로 오지 않습니다. 그러나 DO-LOOP에서 동일한 작업을 수행하는 방식으로 호기심을 자극합니다. 다시는 실제로 필요하지 않습니다. CL은 광대 한 언어이므로 직접 구문 질문이나 actial 요구 사항의 제약 조건을 권장합니다. 종종 후자는 "오, 우리는 그걸 XXX로 사용합니다"라고 대답하는 것이 가장 좋습니다. – kennytilton

답변

1

어떻게?에 관하여 할

좀 더 제공하지만 것

((XYZ) = (다중 값 목록 등 (3 발-FN)) ...에 대한 루프) 할 수 없습니다 do-loop를 이해하십시오.

+0

그곳에가는 가장 쉬운 방법 인 것 같습니다! –

5

표준 반복 구문의 여러 값은 실제로 지원되지 않습니다.

LOOP로 당신의 조각은 다음과 같습니다

(loop with x and y and z 
     do (setf (values x y z) (3-val-fn)) 
     while (equal y 'some-val) 
     finally (return y) 
     do ...) 

나는 종종 그런 일을해야하는 경우, 나는 위의 코드로 확장 할 이는 do-mv 매크로를 정의 할 수 있습니다.

(do-mv ((x y z) (3-val-fn)) 
     ((equal y 'some-val) y) 
    ...) 

이상 사용하는 장점은 각 반복시 여러 값에서 목록을 생성하지 않는다는 것입니다 : 같은 코드는 보일 것이다. 여러 값 중에서 목록을 만들면 여러 값의 목적을 상실하게됩니다.이 값은 둘 이상의 값을 반환하고 효율적인 방법으로 구현할 수 있도록합니다.

1

그것은 do*으로 행할 (정렬의)입니다 :

여기
(defun foo (n) 
    (do* ((n n (1- n)) 
    (values (multiple-value-list (truncate 17 n)) 
     (multiple-value-list (truncate 17 n))) 
    (result (first values) (first values)) 
    (remainder (second values) (second values))) 
     ((< n 3) nil) 
    (format t "Result: ~d, remainder: ~d, n: ~d~%" result remainder n))) 

우리가 먼저 목록에 다중 값 함수 결과를 변환 변수에 그 바인딩 한 후 수동으로 destructure. 그러나 반복 구조의 do 패밀리가 정말로 loop을 사용하는 것보다 훨씬 더 나은 선택이 아니라면, 읽기가 어렵고 아마도 피해야합니다.