You need a level of indirection. One way is to make the backward
reference from accounts to owners be based on a non-pointer primary
key (maybe a keyword) that can be resolved through some table. This is
how it works in relational database systems

If you want to use references of some sort, mutability (possibly
implicit) is required. Here's an example of implicit mutation via
delay/force:

(deftype Account [owner balance])
(deftype Person [name accounts])

(declare per)

(def per-account1 (Account (delay per) 42))
(def per-account2 (Account (delay per) 9000))

(def per (Person "Per" [per-account1, per-account2]))

(:name @(:owner per-account1)) ;; "Per"

Note that you will need to dereference backward references explicitly.

In this example, I also relied on forward declaration of vars for
tying the circular knots. If you want to this within functions, you'll
need something like letrec. Here's a proof of concept I did a while
ago:

http://gist.github.com/336461

With that, you could write the above as follows:

(letrec [per-account1 (Account (delay per) 42)
           per-account2 (Account (delay per) 9000)
           per (Person "Per" [(delay per-account1), (delay per-account2)])]
  (:name @(:owner per-account1)))

Unfortunately, because of the way my letrec implementation works,  you
will need to delay both forward and backward references.

By the way, as you will quickly see if you play around with this kind
of code in the REPL, you must be careful with circular references:
it's very easy to send the printer into an infinite loop. You can do a
(set! *print-level* <some small number>) to prevent this from
happening.

-Per

On Mon, Apr 5, 2010 at 2:09 PM, Sophie <itsme...@hotmail.com> wrote:
> (deftype Account [owner balance])
> (deftype Person [accounts])
>
> joe has 1 account.
>
> How to I create / initialize joe & the account with mutual references?
> I'd rather not use refs.
>
> Thanks!
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>
> To unsubscribe, reply using "remove me" as the subject.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to