Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

defining mutually dependent variables

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?

like image 292
Vladimir Matveev Avatar asked Dec 30 '25 11:12

Vladimir Matveev


2 Answers

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]}}
like image 164
mikera Avatar answered Jan 01 '26 01:01

mikera


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]
like image 30
Alex Taggart Avatar answered Jan 01 '26 00:01

Alex Taggart



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!