2017-03-16 2 views
3

Clojure에서 함수 리터럴에 원하는 수의 인수를 사용할 수 있지만 실제로는 사용하지 않습니다. 그래서 %& (함수 리터럴의 경우 '나머지 arg')과 #_ ('discard'독자 매크로)을 발견했습니다.'rest arguments'매크로가있는 Clojure 함수 리터럴 'discard'reader 매크로

=> (macroexpand `#(... #_ %&)) 
(fn* [& rest__125459__125460__auto__] (...)) 

이 내가 원하는 것을 보이는 (그리고 결국 작동하는 것 같다)하지만, 폐기 매크로가 작동하는데 어떻게입니다 :

하지만 어떻게 그들이 함께 일할 나를 놀라게? 문서 says :

# _ 다음의 양식은 독자가 완전히 건너 뜁니다.

여기 분명히 무시 된 %& 양식은 부작용이 있습니다. 즉 리터럴 인수 목록에 영향을 미칩니다. 이 동작에 의존해야합니까, 아니면 더 버그처럼 보입니까?

답변

0

내가 너무 빨리 말했고, 아마도 버그가 아니며, 일 수도 있고, 어쩌면 이건 허용되어서는 안되며 오류가 발생합니다. 하지만 실제로 #_양식이고, %&은 양식이 아닙니다. but also a reader macro입니다.

그래서 #_%&#[email protected]과 같습니다. #_;이며 작동하지 않습니다. 폐기 리더 #_은 (등) () 또는 [] 같은 "진짜 형태"#_ 의도되지 않은 매크로 폐기 리더가 단독으로 사용하는

2

와 함께 사용할 수있다. 여기에 행동에 그것을 볼 수 있습니다

(println "first") 
(do 
    (print "second ") 
    (dotimes [i 5] 
    (print i " ")) 
    (newline)) 
(println "third") 

first 
second 0 1 2 3 4 
third 

이후 :

전에

(println "first") 
#_(do 
    (print "second ") 
    (dotimes [i 5] 
     (print i " ")) 
    (newline)) 
(println "third") 

first 
third 

그래서 추가 #_ (재귀)가 적용되는 형태로 내부의 모든 것을 삭제합니다.

무시 인수의 원래의 질문에 대해서는, 당신은 몇 가지 선택이있다 :

(mapv #(do %& 42)  (range 3)) => [42 42 42] 
(mapv (fn [& _] 42) (range 3)) => [42 42 42] 
(mapv (constantly 42) (range 3)) => [42 42 42] 
+0

감사합니다, 나는에 무엇'# _' 매크로를 이해하고 어떻게 정상적으로 동작합니다. 제 질문은 특별히 # # %의 조합과 명백한 부작용이 의도 된 것인지에 관한 것입니다. 어쩌면 질문 제목을 조금 바꾸어 말해야 할 것 같습니다. – alex

0

#_ 절은 폼에 적용됩니다. 귀하의 예에서는 그 뒤에 공백이 있으므로 효과가 없습니다.

앞에 추가가 #_ 어떤 목록/양식을 완전히 무시 :

#_(do (print 42) (/ 0 0)) ;; there won't be an error

+0

사실,'# _' 다음에 공백이 있는지 여부는 중요하지 않습니다. – alex