Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clojure with multiple if statements

Tags:

clojure

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)
like image 980
jeshaitan Avatar asked Feb 10 '14 15:02

jeshaitan


3 Answers

The problem is that your function is a sequence of two-clause if-forms.

  • Clojure performs the elements of the sequence in turn, returning the result of the last.
  • If the condition fails, a two-clause 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))
like image 170
Thumbnail Avatar answered Oct 17 '22 23:10

Thumbnail


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.

like image 20
onit Avatar answered Oct 17 '22 22:10

onit


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
like image 5
ChrisDevo Avatar answered Oct 17 '22 22:10

ChrisDevo