when I call the math() function, to "times", the REPL returns nil. when I use "add", it works fine... help!
(defn math [opr x y ]
(if(= opr "times")
(* x y)
)
(if(= opr "add")
(+ x y)
)
)
(math "times" 8 8)
The problem is that your function is a sequence of two-clause if-forms.
if-form returns nil.The quickest repair is, as WeGi suggested, to nest the ifs:
(defn math [opr x y]
(if (= opr "times")
(* x y)
(if (= opr "add")
(+ x y))))
However, there are better ways:
(defn math [opr x y]
(case opr
"add" (+ x y)
"times" (* x y)))
... and, leaving C / Java idioms behind, ...
(defn math [opr x y]
((case opr
"add" +
"times" *)
x y))
... or ...
(defn math [opr x y]
(({"add" +, "times" *} opr) x y))
I like using a cond statement for multiple conditions.
;; Will return nil if the cond statement fails all the predicates
(defn math [opr x y ]
(cond (= opr "times") (* x y)
(= opr "add") (+ x y)))
WeGi is correct in that Clojure will always return the last statement in the function.
condp works when all your predicates have the same structure:
(defn my-calc
[operator x y]
(condp = operator
"times" (* x y)
"plus" (+ x y)))
=> (var user/my-calc)
(my-calc "times" 2 3)
=> 6
(my-calc "plus" 2 3)
=> 5
In Clojure the last statement is the Return Statement. So Clojure Checks for "times", even if it is true it checks then for "add" and because your call is made with "times" the second if evaluates to nil. Which is returned.
You could use do or nest your if statements to solve your Problem.
do alone won't solve the problem, as do still returns its tail value. Using do would require a side-effect, and be nasty. cond or if nesting are the only really correct answers here.
oprdoes not equal"add", the return value is alwaysnil. You may want to consider using a case statement.