Clojure에서 doseq와 for의 차이점


105

Clojure에서 doseq와 for의 차이점은 무엇입니까? 다른 것을 사용하기로 선택한 경우의 몇 가지 예는 무엇입니까?

답변:


167

차이점은 for지연 시퀀스를 만들고 반환하는 동안 doseq부작용을 실행하고 nil을 반환한다는 것 입니다.

user=> (for [x [1 2 3]] (+ x 5))
(6 7 8)
user=> (doseq [x [1 2 3]] (+ x 5))
nil
user=> (doseq [x [1 2 3]] (println x))
1
2
3
nil

다른 시퀀스를 기반으로 새 시퀀스를 작성하려면 for를 사용하십시오. 일부 시퀀스의 요소를 기반으로 부작용 (인쇄, 데이터베이스에 쓰기, 핵탄두 발사 등)을 수행하려면 doseq를 사용하십시오.


11
지금은 많은 부작용이 있습니다 ... 핵탄두 발사 :)
Marc

6
감사! 나는 내 (오래 사라진) 머리카락을 "for"로 잡아 당겨서 내 항목 목록에 내 핵탄두를 발사하지 않았습니다. "doseq"는 확실히했습니다.
Yu Shen

이것은 구별하는 좋은 방법입니다.
jskulski

60

또한 게 으르 doseq면서 열망 for합니다. Rayne의 답변에 누락 된 예는 다음과 같습니다.

(for [x [1 2 3]] (println x))

REPL에서 이것은 일반적으로 원하는 것을 수행하지만 기본적으로 우연 for입니다. 비대화 형 환경에서는 아무것도 인쇄되지 않습니다. 결과를 비교하여 실제로 확인할 수 있습니다.

user> (def lazy (for [x [1 2 3]] (println 'lazy x)))
#'user/lazy

user> (def eager (doseq [x [1 2 3]] (println 'eager x)))
eager 1
eager 2
eager 3
#'user/eager

def양식은 생성 된 새 var를 반환하고 여기에 바인딩 된 값을 반환 하기 때문에 REPL이 인쇄 lazy할 항목이 없으며 실현되지 않은 lazy-seq를 참조합니다. 요소가 전혀 계산되지 않았습니다. eager을 참조 nil하고 모든 인쇄가 완료됩니다.


doseq는 무한 게으른 시퀀스의 평가를 어떻게 처리합니까? 나쁜 생각? 열망 또는 게으른 유한 시퀀스에서만 호출합니까?
johnbakers 2014 년

@johnbakers 평가가 중단 될 때까지 영원히 차단됩니다. Clojure는 유한 시퀀스와 다른 방식으로 무한 시퀀스를 처리하려고 시도하지 않습니다.
Radon Rosborough
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.