Paul C
Paul C

Reputation: 8457

A less cumbersome pattern for checking function parameters for nil in Clojure without throwing an assertion?

This was asked here, but the answers are all unacceptable.

I'm trying to apply some defensive programming techniques to clojure and I'm finding some things cumbersome.

Like checking function parameters:

(defn my-tolower [s]
  (if (nil? s) nil
               (.toLowerCase s)
               ))

Is there a cleaner way to do this?

I'm aware of :pre, but that throws an exception.

Upvotes: 0

Views: 155

Answers (3)

birdspider
birdspider

Reputation: 3074

there are other aproaches too:

fnil, probably what I'd do

clojure.core/fnil
([f x] [f x y] [f x y z])
  Takes a function f, and returns a function that calls f, replacing
  a nil first argument to f with the supplied value x. Higher arity
  versions can replace arguments in the second and third
  positions (y, z). Note that the function f can take any number of
  arguments, not just the one(s) being nil-patched.

provide a default value for a nil accepting fn. /

(let [f (fnil str/lower-case "")]
  (f nil))
""

or catching the NPE

(let [f str/lower-case] 
  (try (f nil) 
    (catch NullPointerException ne nil)))
""

or just str

(.toLowerCase (str nil))
""

alternativly defprotocol and extend-protocol for nil maybe

Upvotes: 1

Alan Thompson
Alan Thompson

Reputation: 29958

It seems you simply want some->, no?

(defn my-tolower [s]
  (some-> s .toLowerCase))

(my-tolower "HELLO") => "hello"
(my-tolower     nil) => nil

or just inline it without the wrapper function:

(some-> "HELLO" .toLowerCase)   => "hello"
(some->  nil    .toLowerCase)   => nil

Upvotes: 4

Lee
Lee

Reputation: 144126

Since nil is falsey you could use when:

(when s (.toLowerCase s))

if you want the test you could use some? instead of nil?:

(if (some? s) (.toLowerCase s))

Upvotes: 1

Related Questions