2012-02-17 4 views
3

상호 의존적 인 변수를 정의해야합니다. 이 말은 하나의 변수가 예를 들어. 다른 var와 vector는 그 반대입니다. 분명히상호 종속 변수 정의

test=> (first a) 
1 
test=> (second a) 
#<Unbound Unbound: #'test/b> 
test=> (first b) 
[1 #<Unbound Unbound: #'test/b>] 
test=> (second b) 
2 

작동해야하지 어떻게 먹으 렴 :

(declare a b) 
(def a [1 b]) 
(def b [a 2]) 

그러나이 코드를로드 한 후 나는이 얻을 : 이것은 다음과 같은 코드에 의해 설명된다. 이러한 구조를 인쇄하면 스택 오버플로가 발생하지만 인쇄 할 필요가 없음을 알고 있습니다. 어떻게해야합니까?

답변

3

는 다음과 같은 작업을 수행 할 수 있습니다 #'는 VAR 참조에 대한 독자 매크로가

(declare a b) 
(def a [1 #'b]) 
(def b [#'a 2]) 

@(a 1) 
=> [#'user/a 2] 

하는 것으로.

나는 아직도 당신이 이것을하고 싶어하는지 확신 할 수 없다. vars를 상호 의존적으로 만들려고 노력하는 것은 나에게 꽤 나쁜 코드 냄새처럼 보인다. 당신이하려고하는 것은 실제로 다른 접근법에 의해 가장 잘 해결 될 것입니다.

여분의 댓글이 문제가 서로 참조하는 개체의 다른 유형을 가진 관련이 없다는으로 편집

, 내가 생각하는 더 나은 방법은 예를 들어, 키워드와지도입니다

(def my-model 
    {:a 
     {:name "Entity A" 
     :references [:b]} 
    :b 
     {:name "Entity B" 
     :references [:a]}} 
+1

예, 저는 vars로 뭔가를해야한다고 생각했습니다. 감사. 제가하고 싶은 것은 다음과 같습니다. 나는 몇몇 엔티티의 어떤 종류의 타입들 사이에 (잠재적으로) 다 대다 관계를 기술 할 필요가있다. 이러한 유형과 그 관계는 일정합니다. 서로에 대한 참조를 갖는 vars로 정의하고 싶습니다. 그래서 다른 타입에 의해 참조되는 타입을 얻고 싶다면'(first (: references src-type))'과 같은 간단한 것을 할 수 있습니다. –

+0

당신은 아마 맞을 것입니다, 아마도 전 세계적인 유형의지도를 사용해야하고 단순한 키워드로 참조해야합니다. 너는 무엇을 생각 하는가? 더 나은 접근 방법이 될 것인가? –

+1

예, 키워드가있는 큰지도가 가장 잘 작동한다고 생각합니다. 데이터 만 있으면됩니다. 복사본을 만들고, 직렬화하거나, 테스트 케이스 등을 위해 다른 버전을 만들고 싶을 수도 있습니다.지도를 사용하면 쉽게 될 수 있지만 바스를 사용하려고하면 매우 까다 롭습니다 ..... – mikera

1

먼저이 문제는 XY 문제와 매우 흡사합니다.

둘째, 상호 참조 데이터 구조는 상태 변경없이 만들 수 없습니다. 이것이 필요한 데이터 구조라면 (아마도 그렇지 않을 수도 있습니다) clojure의 매우 잘 설계된 접근 방법을 사용하십시오. 예를 들어 :

user=> (set! *print-level* 2) ; this is necessary to stop the infinite print recursion 
2 
user=> (def a (atom [1])) 
#'user/a 
user=> (def b (atom [a 2])) 
#'user/b 
user=> (swap! a conj b) 
[1 #<[email protected]: #>] 
user=> @a 
[1 #<[email protected]: #>] 
user=> @b 
[#<[email protected]: #> 2] 
0

게으른 평가가 도움이 될 수 있습니다 :

user=> (declare a b) 
#'user/b 
user=> (def a [1 (lazy-seq b)]) 
#'user/a 
user=> (def b [(lazy-seq a) 2]) 
#'user/b 
user=> (first a) 
1 
user=> (second b) 
2 
user=> (second a) ;stack overflow 
user=> (first b) ;stack overflow 
user=> (take 42 (second a)) ;still overflow as it's infinitely deep 
user=> (take 42 (first b)) ;still overflow as it's infinitely deep 

내가 그것을 유용 할 것 볼 수 없습니다하지만 그것이 도움이되기를 바랍니다.