(defn fact [x]
(loop [n x prod 1] ;; this works just like a 'let' binding.
(if (= 1 n) ;; this is the base case.
prod
(recur (dec n) (* prod n)))))
(println (fact 5)) ;; change 5 to whatever number you like!
;; ...but not more than 20, or you'll get an integer overflow error.
;; to fix this, you can add 'N' to the end of any number to make it a bigint.
;; 21 -> 21N
(defn fact-no-loop [n]
(if (= 1 n)
1
(* n (fact-no-loop (dec n)))))
(println (fact-no-loop 5)) ;; still works!
(time (fact 20))
(time (fact-no-loop 20))
KGRlZm4gZmFjdCBbeF0KICAobG9vcCBbbiB4IHByb2QgMV0gOzsgdGhpcyB3b3JrcyBqdXN0IGxpa2UgYSAnbGV0JyBiaW5kaW5nLgogICAgKGlmICg9IDEgbikgIDs7IHRoaXMgaXMgdGhlIGJhc2UgY2FzZS4KICAgICAgcHJvZAogICAgICAocmVjdXIgKGRlYyBuKSAoKiBwcm9kIG4pKSkpKQoKKHByaW50bG4gKGZhY3QgNSkpIDs7IGNoYW5nZSA1IHRvIHdoYXRldmVyIG51bWJlciB5b3UgbGlrZSEKCjs7IC4uLmJ1dCBub3QgbW9yZSB0aGFuIDIwLCBvciB5b3UnbGwgZ2V0IGFuIGludGVnZXIgb3ZlcmZsb3cgZXJyb3IuCjs7IHRvIGZpeCB0aGlzLCB5b3UgY2FuIGFkZCAnTicgdG8gdGhlIGVuZCBvZiBhbnkgbnVtYmVyIHRvIG1ha2UgaXQgYSBiaWdpbnQuCjs7IDIxIC0+IDIxTgoKKGRlZm4gZmFjdC1uby1sb29wIFtuXQogIChpZiAoPSAxIG4pCiAgICAxCiAgICAoKiBuIChmYWN0LW5vLWxvb3AgKGRlYyBuKSkpKSkKCihwcmludGxuIChmYWN0LW5vLWxvb3AgNSkpIDs7IHN0aWxsIHdvcmtzIQoKKHRpbWUgKGZhY3QgMjApKQoKKHRpbWUgKGZhY3Qtbm8tbG9vcCAyMCkpCg==