In this post I’ll compare a recursive factorial function written in PHP and another written in Clojure.
Recursive Factorial
PHP
/**
* Calculate the factorial of n
*/
function factorial($n) { //Define a function, takes one argument, n.
if($n == 1)
return 1; // IF, do this
else
return $n * factorial(($n - 1)); // ELSE, do this
}
echo factorial(5) . PHP_EOL; //120
Clojure
(defn factorial [n] ;; Define a function, takes one argument, n.
"Calculate the factorial of n" ;; This is like PHPDOC
(if (= n 1)
1 ;; IF, do this
(* n (factorial (- n 1))))) ;; ELSE, do this
(println (factorial 5)) ;; 120
The most interesting thing here are Clojures ifs. The if is a function that take three arguments:
- The condition.
((= n 1)
- The expression to execute if the condition is true.
1 (return 1; in php.)
- The expression to execute if the condition is false.
(* n (factorial (- n 1)))
If we had written this function in PHP(+5.3.0) it would be something like this:
function my_if($condition, $ifTrue, $ifFalse) {
//...
}
my_if("$n == 1",
function() {
return 1;
},
function() {
return $n * factorial(($n - 1));
}
}
Practice time
Take some time and try to write the factorial functions by your self. Or try to write a summation function.
You will probably sooner or later get the error “… Too many arguments to if, …”. This happens when you write code something like this:
(defn faculty [n]
"Calculate the faculty of n"
(if (= n 1) ;; First argument, the condition
1 ;; Do this if true
(println "Debug N, to be sure I'm doing this shit right: ", n) ;; Do this if false
(* n (faculty (- n 1))))) ;; Do this if... wait! Wtf? Get it? This is a fourth argument, one argument too much.
The problem here is that you now have passed four arguments to the if, the function if can only take three arguments. If you don’t understand look at the PHP code and compare. Anyway to solve this problem you can wrap code in something called do.
The new code:
(defn faculty [n]
"Calculate the faculty of n"
(if (= n 1) ;; First argument, the condition
1 ;; Do this if true
(do ;; Do this if false:
(println "Debug N, to be sure I'm doing this shit right: ", n) ;; I'm in the 'do' block!
(* n (faculty (- n 1)))))) ;; Me too!
Okay, that’s everything for now. Hope you have learned something new. Bai!