Clojure post-condition, sözdizimi hatası nedeniyle yürütmeyi başaramıyor - neden?

Bu fonksiyonda:

(defn my-post 
  [a] 
  {:post (number? %)}
  a)

Durum koşulu yürütmez (veya en azından bir onaylama hatasına neden olmaz). Şimdi bunun olması gerektiğini biliyorum:

(defn my-post 
  [a] 
  {:post [(number? %)]} ;; note the square brackets around the expression
  a)

Aslında, doğru şekilde çalışıyor.

Sorun şu ki, bu sessizce başarısız oldu ve neyin yanlış olduğunu anlamak için biraz zamanımı aldı. Sözdizimi hatası yok, çalışma zamanı istisnaları.

I would like to understand what Clojure does with this code, in order to understand why Clojure didn't complain. Macro expansions? Destructuring? Does the code just disappear if it doesn't see square braces?

3
Lütfen bu yazı durumunun ne olduğunu açıkla? Bu yöntem amacının ne olduğunu anlayamıyorum.
katma yazar Abimaran Kugathasan, kaynak

1 cevap

http://clojure.org/special_forms documents that the condition-map for fn (thus also defn) should be of the form:

{:pre [pre-expr*]
 :post [post-expr*]}

{:post (number? %)} will result in (number? %) being treated as a sequence of assertions, which means it's interpreted as two separate assertions: number? and %.

user> (macroexpand-1 '(fn [a] {:post (number? %)} a))
(fn*
 ([a]
  (clojure.core/let [% a]
   (clojure.core/assert number?)
   (clojure.core/assert %)
   %)))

(assert number?) always passes as long as number? is defined and has a true value, which being a core function, it probably does. (clojure.core/assert %) passes if % has a true value. It's bound to the value of your argument a via the let, so it passes if a has a true value. Try calling (my-post nil) with your first function definition and it'll fail the assertion.

user> (my-post nil)
; Evaluation aborted.
; Assert failed: %
;  [Thrown class java.lang.AssertionError]

Durumunuzu bir vektöre doğru bir şekilde koyarsanız, şu şekilde genişler:

user> (macroexpand-1 '(fn [a] {:post [(number? %)]} a))
(fn*
 ([a]
  (clojure.core/let [% a]
   (clojure.core/assert (number? %))
   %)))
5
katma