I need to define mutually-dependent vars. By this I mean that one var contains e.g. a vector with another var and vice versa. This is illustrated by the following code:
(declare a b)
(def a [1 b])
(def b [a 2])
But after loading this code I get this:
test=> (first a)
1
test=> (second a)
#<Unbound Unbound: #'test/b>
test=> (first b)
[1 #<Unbound Unbound: #'test/b>]
test=> (second b)
2
clearly, thats not how it should work. I understand that printing such structure will give stack overflow, but I don't need to print it. How should I do it?
You can do the following:
(declare a b)
(def a [1 #'b])
(def b [#'a 2])
@(a 1)
=> [#'user/a 2]
Note that #' is a reader macro for referring to a var.
I'm still not quite sure why you want to do this though..... trying to make vars mutually dependent like this seems like a pretty bad code smell to me. It's likely that whatever you are trying to do would actually be best solved by a different approach.
EDIT
With the extra comment stating that the problem is related to having different types of entities referring to each other, I think a better approach is a map with keywords, e.g.
(def my-model
{:a
{:name "Entity A"
:references [:b]}
:b
{:name "Entity B"
:references [:a]}}
First, this smells very much like an XY problem.
Second, mutually referential data structures cannot be created without mutating state. If that's the data structure you need (and you probably don't), then use clojure's very well designed approach to state. For example:
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With