Why (decrease * []) ​​is evaluated to 1?

In clojure, calling reduce *en on an empty collection returns 1. This is pretty surprising.

I made this discovery by creating a factor function defined as follows:

(defn factorial [n] (reduce * (take-while #(> % 0) (iterate dec n))))

(factorial 0)returns correctly 1, without the need to write a special case for zero. Why?

+4
source share
2 answers

Checking Code *and +shows that these two functions implement case 0-arity, returning an identifier for an operation. In case of *code (with disabling dosctring and metadata):

(defn *
  ([] 1)
  ([x] (cast Number x))
  ([x y] (. clojure.lang.Numbers (multiply x y)))
  ([x y & more]
     (reduce1 * (* x y) more)))
+7
source

The main thing here is behavior reduce. AT

(reduce f s)

... if sempty, the call returns (f).

(*) 1,

(reduce * ())
; 1

reduce , 1 *. 1 /,

(reduce / ())
; ArityException Wrong number of args (0) passed to: core$-SLASH- ...

... , , / 0 arity.

0

Source: https://habr.com/ru/post/1542508/


All Articles