Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a quick way to check for nil args in a Clojure function?

Tags:

null

clojure

In Phil Hagelberg's (technomancy) gripes file he states the following about Clojure:

nil is everywhere and causes bugs that are difficult to find the source

Now Phil is a smart guy who has contributed a lot to the Clojure community, and everyone uses his stuff - so I thought this was worth pondering for a moment.

One easy way to manage nil args to a function is to throw an error:

(defn myfunc [myarg1]
  (when (nil? myarg1) 
    (throw (Exception. "nil arg for myfunc")))
  (prn "done!"))

These two extra lines per argument reek of boilerplate. Is there an idiomatic way to remove them via metadata or macros?

My question is Is there a quick way to check for nil args in a Clojure function?

like image 740
hawkeye Avatar asked Mar 06 '14 10:03

hawkeye


People also ask

What does nil mean in Clojure?

nil is a possible value of any data type in Clojure. nil has the same value as Java null. The Clojure conditional system is based around nil and false, with nil and false representing the values of logical falsity in conditional tests - anything else is logical truth.

What is FN in Clojure?

Most Clojure code consists primarily of pure functions (no side effects), so invoking with the same inputs yields the same output. defn defines a named function: ;; name params body ;; ----- ------ ------------------- (defn greet [name] (str "Hello, " name) )

Is Clojure null?

The only difference between nil and null is that one is Clojure and the other is Java, but they're essentially aliases, converted back and forth seamlessly as needed by the reader and printer when going from Clojure to Java to Clojure.


1 Answers

There is a clojure language based solution for these situations: http://clojure.org/special_forms#toc10

(defn constrained-sqr [x]
    {:pre  [(pos? x)]
     :post [(> % 16), (< % 225)]}
    (* x x))

Adapted to your requirements:

(defn constrained-fn [ x]
  {:pre  [(not (nil? x))]}
  x)
(constrained-fn nil)
=> AssertionError Assert failed: (not (nil? x))  ...../constrained-fn (form-init5503436370123861447.clj:1)

And there is also the @fogus contrib library core.contracts, a more sophisticated tool

More info on this page http://blog.fogus.me/2009/12/21/clojures-pre-and-post/

like image 111
tangrammer Avatar answered Oct 04 '22 03:10

tangrammer