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.