honeybadger
honeybadger

Reputation: 1575

Nested Let in Anglican Clojure

I am new to Anglican, the Probabilistic programming language in Clojure. I am trying to use a nested let construct in Clojure.

The following defqueryruns without any issues.

(defquery panda3 [p1]
  (let [p2 (sample 
              (categorical
                {:speA (/ 1 2),
                 :speB (/ 1 2)}))]
    (if (= p2 :speA)
      ( let [p3 (sample 
              (categorical
                {:twins (/ 1 10),
                 :notwins (/ 9 10)}))] 

      )
      ( let [p3 (sample 
              (categorical
                {:twins (/ 2 10),
                 :notwins (/ 8 10)}))]

      ))

    p2))

However, instead of returning the value of p2 at the end, if I try to return the value of p3, it returns errors.

(defquery panda3 [p1]
  (let [p2 (sample 
              (categorical
                {:speA (/ 1 2),
                 :speB (/ 1 2)}))]
    (if (= p2 :speA)
      ( let [p3 (sample 
              (categorical
                {:twins (/ 1 10),
                 :notwins (/ 9 10)}))] 

      )
      ( let [p3 (sample 
              (categorical
                {:twins (/ 2 10),
                 :notwins (/ 8 10)}))]

      ))

    p3))

The idea is to assign p3 based on the outcome of p2. However, I am unable to do so. What am I doing wrong?

Thanks in advance,

Upvotes: 0

Views: 178

Answers (1)

Alan Thompson
Alan Thompson

Reputation: 29958

As the comment said, you need to return p3 from within the scope of the let in which it is defined:

(defquery panda3 [p1]
  (let [p2 (sample 
              (categorical
                {:speA (/ 1 2),
                 :speB (/ 1 2)}))]
    (if (= p2 :speA)
      (let [p3 (sample 
                 (categorical
                   {:twins (/ 1 10),
                    :notwins (/ 9 10)}))] 
        p3)
      (let [p3 (sample 
                 (categorical
                   {:twins (/ 2 10),
                    :notwins (/ 8 10)}))]
        p3 ))))

Update

As amalloy points out, the 2nd part could be:

  ; return the result of `(sample (categorical ...))` called
  ; with one of the 2 maps
  (if (= p2 :speA)
    (sample 
      (categorical
        {:twins (/ 1 10),
         :notwins (/ 9 10)} ))
    (sample 
      (categorical
        {:twins (/ 2 10),
         :notwins (/ 8 10)} )))

or even

  ; return the result of `(sample (categorical ...))` called
  ; with one of the 2 maps
  (sample 
    (categorical
      (if (= p2 :speA)
        {:twins (/ 1 10),
         :notwins (/ 9 10)}
        {:twins (/ 2 10),
         :notwins (/ 8 10)} )))

Upvotes: 2

Related Questions