Question

Je dois définir vars mutuellement dépendants. Par là, je veux dire que l'on var contient par exemple un vecteur avec un autre var et vice versa. Ceci est illustré par le code suivant:

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

Mais après le chargement de ce code, j'obtiens ceci:

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

clairement, thats pas comment cela devrait fonctionner. Je comprends que l'impression telle structure donnera débordement de la pile, mais je ne ai pas besoin de l'imprimer. Comment dois-je faire?

Était-ce utile?

La solution

Vous pouvez faire ce qui suit:

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

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

Notez que #' est une macro de lecteur pour se référer à un var.

Je ne suis pas encore tout à fait sûr pourquoi vous voulez le faire bien ..... essayer de faire vars mutuellement dépendants comme cela semble être une odeur de code assez mauvais pour moi. Il est probable que tout ce que vous essayez de faire serait effectivement mieux résolu par une approche différente.

EDIT

Avec le commentaire supplémentaire indiquant que le problème est lié à avoir différents types d'entités faisant référence à l'autre, je pense une meilleure approche est une carte avec des mots-clés, par exemple.

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

Autres conseils

D'abord, cela sent très bien comme un problème XY.

D'autre part, les structures de données mutuellement référentiel ne peut être créé sans état muter. Si c'est la structure de données dont vous avez besoin (et que vous ne probablement pas), puis utilisez l'approche de clojure très bien conçu à l'autre. Par exemple:

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 #<Atom@19ed00d1: #>]
user=> @a
[1 #<Atom@19ed00d1: #>]
user=> @b
[#<Atom@5c6c2308: #> 2]

Évaluation Lazy pourrait aider:

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

espère que cela aide, mais je ne vois pas comment il va être utile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top