Search code examples
clojurevarpreconditions

clojure: var defined inside function is breaking precondition


I have this function:

 (defn executa-peso-individuo 
   [estado-individuo transicao-individuo]
   (def tipos-transicoes-peso #{:troca-peso :mesmo-peso})
   (def tipos-estados-peso #{:d :e})
   {:pre [(contains? tipos-transicoes-peso
                     (:peso transicao-individuo))
          (contains? tipos-estados-peso
                     (:peso estado-individuo))]
   ...

Preconditions are not working. Somehow the vars tipos-transicoes-pes and tipos-estados-peso are creating a bug in the precondition code. I know I can put those vars outside my function to make it work. But I would like to keep those definitions inside my function. How can I do that?


Solution

  • In order for the pre- and post-conditions map to be recognized as such, it must immediately follow the parameter vector. See http://clojure.org/special_forms#toc10.

    An acceptable albeit not very common way to package these would be to wrap your defn in a let

     (let [tipos-transicoes-peso #{:troca-peso :mesmo-peso}
           tipos-estados-peso #{:d :e}]
       (defn executa-peso-individuo 
         [estado-individuo transicao-individuo]
         {:pre [(contains? tipos-transicoes-peso
                           (:peso transicao-individuo))
                (contains? tipos-estados-peso
                           (:peso estado-individuo))]
         ...
    

    In general, reserve def and defn for top-level use only. Inside a top-level let is okay, but again, not common. But, definitely do not use inside a function body as in your example.