2

The title is not that great, but it is difficult to find a good one-liner :)

The question is the following. Given the declaration:

(def mystruct (create-struct :a :b :c))

is it possible to build an instance the following way (something similar, obviously):

(struct-map mystruct :a 1 :b 2 :c (inc (:b this)))

I managed to get something like this in the following bizzaro way:

(def mystructinst (struct-map mystruct :a 1 :b 2 :c (inc (:b mystructinst))))

But to be honest, I don't know why that worked. I thought mystructinst is only bound after the evaluation of the contained forms. Is this a clean way of performing this task? Is there any better one?

Thank you for your time.

Tudor Vintilescu
  • 1,450
  • 2
  • 16
  • 28
  • 1
    Same wavelength: http://stackoverflow.com/questions/11651420/advice-discussion-on-anonymous-self-referential-data-structures – Omri Bernstein Jan 24 '13 at 17:57
  • @OmriBernstein thank you, that's a great link and it sure is the same thing as what I was trying to achieve. However, I'm left to wonder about why the construct I proposed works. – Tudor Vintilescu Jan 24 '13 at 18:08
  • 2
    @TudorVintilescu: Your last code doesn't work (throws null pointer ex). It may have worked in your case because while trying things out you have already defined a `mystructinst` – Ankur Jan 25 '13 at 04:17
  • BTW, struct-maps are quasi-deprecated now in favor of records. https://groups.google.com/d/msg/clojure/pnDl4OgzqBM/zjDioSsxkvEJ – Paul Legato May 06 '13 at 04:36

1 Answers1

0

How about just:

(let [b 2] (struct-map mystruct :a 1 :b b :c (inc b)))

You are correct that the symbol is bound only after the evaluation of the contained forms when using def, which is why your last example throws a NullPointerException. You probably predefined mystructinst somewhere else without realizing it. You can move the variable you want to reference outside the struct-map and put it in a let instead. Then, it'll be accessible anywhere.

Also, note that let does allow you to refer to previous bindings in subsequent ones:

user=> (let [a 1 b (inc a)] b)
2
Paul Legato
  • 1,202
  • 13
  • 11