Clojure: nth не поддерживается для этого типа: Boolean"

Я пытаюсь реализовать пример обедающего философа в clojure. По некоторым причинам моя программа всегда умирает с исключением, говорящим

«java.lang.UnsupportedOperationException: nth не поддерживается для этого типа: логическое значение»

Я не могу понять это сообщение об ошибке, так как я уже пытался получить логические значения из списка, который отлично работал с nth

Я предполагаю, что ошибка возникает в операторе if в функции philosopher-thread

Печать консоли:

  • 3 думает
  • 1 думает
  • 4 думает
  • 0 думает
  • 2 думает
  • 0 после сна
  • 0 после подумав
  • 0 своп
  • 0 ест
  • 3 после сна
  • 3 после подумав

Код:

(ns dining-philosphers.core
  (:gen-class))

(defn think [n] 
  (println (str n " is thinking"))
  (Thread/sleep (rand 1000))
  (println (str n " after sleep"))
)

(defn eat [n] 
  (println (str n " is eating"))
  (Thread/sleep (rand 1000))
)

(def isEating (atom '(false false false false false)))


(defn philosopher-thread [n] 
  (Thread. #( 
    (while true (do  
      (think n) 
      (println (str n " after think"))
      (if (or  (nth @isEating (mod (- n 1) 5))  (nth @isEating  (mod (+ n 1) 5)))
        (println "is waiting for neighbour")
        (
          do 
          (println (str n " swap"))
          (swap! isEating (fn [l] assoc l n true)) 
          (eat n)
          (swap! isEating (fn [l] assoc l n true))
        )
      )
     )
    ) 
  )

  )
)

(defn -main [& args] 
  (let [threads (map philosopher-thread (range 5))] 
    (doseq [thread threads] (.start thread))
    (doseq [thread threads] (.join thread))))

person TruckerCat    schedule 11.11.2016    source источник


Ответы (1)


Здесь вам не хватает парочки:

(swap! isEating (fn [l] assoc l n true)) 

должно быть

(swap! isEating (fn [l] (assoc l n true))) 

Первый оценит assoc, l, n и true по порядку и вернет значение последнего выражения (true)

Есть еще проблема, заключающаяся в том, что вы не можете assoc попасть в список. Вместо этого я предлагаю использовать вектор:

(def isEating (atom [false false false false false]))
person Alex    schedule 11.11.2016