나는 Clojure를 배우고있다. 내가 파이썬에 비해 엉뚱한 일을 할 수 있는지, 내가 그랬어 :(def + -) 이후에 빼기 대신 + 연산자를 추가 할 수있는 방법이 있습니까?
놀라 울 일> (+ 2 2)
4
> (def + -)
#'sandbox6693/+
> (+ 2 2)
0
그러나 나는 위의 정의 뒤에 다시 추가 + 얻는 방법을 알아낼 수 없습니다. 그렇게 할 방법이 있습니까?
나는 Clojure를 배우고있다. 내가 파이썬에 비해 엉뚱한 일을 할 수 있는지, 내가 그랬어 :(def + -) 이후에 빼기 대신 + 연산자를 추가 할 수있는 방법이 있습니까?
놀라 울 일> (+ 2 2)
4
> (def + -)
#'sandbox6693/+
> (+ 2 2)
0
그러나 나는 위의 정의 뒤에 다시 추가 + 얻는 방법을 알아낼 수 없습니다. 그렇게 할 방법이 있습니까?
내가 방금 네임 스페이스에서 그것을을 그림자의 clojure.core
기능 +
을 제거하고 생각하지 않습니다.
user=> (def + -)
#'user/+
user=> (+ 2 2)
0
user=> (def + clojure.core/+)
#'user/+
user=> (+ 2 2)
4
을하지만 .... 왜?! :
당신은 네임 스페이스 포함을 참조하여 clojure.core
에서 함수로 +
를 redeffing하여 다시 얻을 수 있습니다
@ Russell이 말했듯이 clojure.core/+
의 섀도우 잉은 user/+
입니다.
내가 Clojure의 실험에 대해 어떻게 할 것인지, (엉망으로하고 싶지 않아 다시 +
과 핵심 +
를 미행하지만, 바인딩 범위 내에서 변경을 유지) 단지 일부 지역의 바인딩을 설정하는 것입니다 :
user> (let [+ -]
(+ 1 2 3))
-4
user> (+ 1 2 3)
6
그러나 당신이 원하는 것을 할 수있는 특별한 방법이 일반적으로 (즉, VAR의 값을 변경 VAR 변경 범위에서 일부 코드를 실행 한 다음 자동으로 값의 복원하는) :
첫 번째 binding
(https://clojuredocs.org/clojure.core/binding) 문제를 사용하는 것입니다. 입니다 만 특별한 dynamic
바르 작동, 그래서 +
이
두 번째 동적 아니기 때문에 그것은 귀하의 경우 실제로 적용 할 수 없습니다, 당신이 필요로 가까이되는 with-redefs
(https://clojuredocs.org/clojure.core/with-redefs)를 사용하는 것입니다,하지만 하나가 이 문제 :
user> (with-redefs [+ -]
(+ 1))
-1 ;; as expected
user> (with-redefs [+ -]
(+ 1 2 3))
6 ;; unexpected!
두 번째 예는 실패, 컴파일러의 인라인 때문에 +
기능, 하나 개 이상의 인수가 자신에게 전달하고 일부 순수 educat를 들어,
또한) add
함수 호출로 대체하는 경우 추가 기능의 컴파일러의 인라인에 흥미 잡았다이다
user> (defmacro redefine [old new & body]
`(let [v# ~old]
(def ~old ~new)
(let [res# (do [email protected])]
(def ~old v#)
res#)))
#'user/redefine
user> (redefine
+ -
(+ 1 2 3))
-4
user> (+ 1 2 3)
6
user> #'+
#'user/+
user> (redefine
+ *
(+ 1 2 4))
8
user> (redefine
+ *
(+ 1 2 4))
8
user> (+ 1 2 4)
7
:하는 ional 목적 당신은, 즉 일반적으로 당신이 필요로하는 모든 것을, 이전 값을 저장하고, 블록 평가 후 복원을 다시 정의 할 매크로를 만들 수 있습니다! – Russell
이것은 훌륭한 대답이지만 Clojure를 처음 접한다면 가능한 한 오랫동안 매크로를 피하는 것이 좋습니다. @Atonal ... 필요한 경우는 거의 없지만 사용하는 경우는 거의 없습니다. 코드 이해 가능성 측면에서 미미한 비용이며 초보자/중간체에서 종종 과용됩니다. – Russell
@Russell 나는 매크로가 약간의 복잡성을 추가하고 때로는 초보자에게 특히 이해하기가 어렵다고 동의하지만, 반면에 그것은 리스프를 마일로 돋보이게하는 환상적인 도구이다. "피하는"대신 "반응 형으로 사용") – leetwinski