2012-07-23 2 views
6

이유는 무엇입니까 Clojure의 코드의이 비트 :Clojure의 지속적 및지도 기능

user=> (map (constantly (println "Loop it.")) (range 0 3)) 

수익률이 출력 :

Loop it. 
(nil nil nil) 

내가이 측면으로 "루프 그것은"세 번 인쇄 기대 함수를 세 번 평가 한 결과.

답변

9

constantly은 인수를 여러 번 평가하지 않습니다. 이것은 함수가 아니라 매크로이므로, 인수는 constantly이 실행되기 전에 정확히 한 번 평가됩니다. 모두 constantly은 (평가 된) 인수를 취하고 호출 될 때마다 지정된 값을 반환하는 함수를 반환합니다 (앞서 말했듯이 인수가 constantly이 실행되기 전에 이미 평가 된 이후로 다시 평가하지 않고).

범위의 모든 요소에 대해 (println "Loop it")을 호출하려는 경우 constantly 대신 매핑 할 함수로 전달해야합니다. 실제로는 평가 된 표현식이 아닌 함수로 전달해야합니다.

+0

출처를 살펴 봅니다. 이것은 승자와 같습니다. – Mike

+0

내가 필요로하지 않는 인수를 명시 적으로 전달하는 것을 피하기 위해 끊임없이 노력했습니다. 그래도 정착 할거야. – Mike

+10

부작용을 원한다면'doseq' 또는'dotimes'를 사용해야합니다. 'map'은 게으르므로'doall' 또는'dorun'으로 강제하지 않는 한 원하는 결과를 얻지 못할 것입니다. –

3

repeatedly과 람다 식을 사용하여 의도와 가까운 행동을 유도 할 수 있습니다. 예를 들어

: 당신이 REPL에서가 아니라면

(repeatedly 3 #(println "Loop it")) 

,이 dorun 또는 유사한 의해 포위 될 필요가있다. repeatedly은 게으름입니다.

+0

Lambda는 내가 전달한 인수를 사용하고자하므로 컴파일되지 않습니다. 이 경우에는 인수를 무시하는 편이 낫습니다. – Mike

+0

나는 너의 것과 비슷한 사용 예제를 추가했다. – sortega

+0

아, 그건 훨씬 의미가 있습니다. 감사! – Mike

3

sepp2k이 올바르게 지적한 것처럼 constantly은 함수이므로 해당 인수는 한 번만 평가됩니다.

사용하는 것입니다 당신이 여기서 뭐하는 달성하는 관용적 인 방법 doseq :

실제로 사용하지 않는 한이 특별한 경우에 좀 더 간결하고 효율적입니다
(doseq [i (range 0 3)] 
    (println "Loop it.")) 

또는 대안 dotimes (range에 의해 생산 순서) :이 솔루션의

(dotimes [i 3] 
    (println "Loop it.")) 

모두 그냥 부작용에 대한 몇 가지 코드를 실행하는 경우 당신이 원하는 아마 인, 비 게으르다.