Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Is there an easier way to process multiple true/false states than using nested if statements? I think there is, and it would be to create a sequence of states, and then use a function like when to determine if all states were true, and drop out if not. I am asking the question to make sure there is not a preferred Clojure way to do this.

Here is the background of my problem:

I have an application that depends on quite a few input files. The application depends on .csv data reports; column headers for each report (.csv files also), so each sequence in the sequence of sequences can be zipped together with its columns for the purposes of creating a smaller sequence; and column files for output data.

I use the following functions to find out if a file is present:

(defn kind [filename]
  (let [f (File. filename)]
    (cond
      (.isFile f)      "file"
      (.isDirectory f) "directory"
      (.exists f)      "other" 
      :else            "(cannot be found)" )))

(defn look-for 
  [filename expected-type]
    (let [find-status (kind-stat filename expected-type)]
      find-status))

And here are the first few lines of a multiple if which looks ugly and is hard to maintain:

(defn extract-re-values
  "Plain old-fashioned sub-routine to process real-estate values / 3rd Q re bills extract."
  [opts]
  (if (= (utl/look-for (:ifm1 opts) "f") 0)             ; got re columns?
    (if (= (utl/look-for (:ifn1 opts) "f") 0)           ; got re data?
      (if (= (utl/look-for (:ifm3 opts) "f") 0)         ; got re values output columns?
        (if (= (utl/look-for (:ifm4 opts) "f") 0)       ; got re_mixed_use_ratio columns?
          (let [re-in-col-nams  (first (utl/fetch-csv-data (:ifm1 opts)))
                re-in-data      (utl/fetch-csv-data (:ifn1 opts))
                re-val-cols-out (first (utl/fetch-csv-data (:ifm3 opts)))
                mu-val-cols-out (first (utl/fetch-csv-data (:ifm4 opts)))
                chk-results     (utl/chk-seq-len re-in-col-nams (first re-in-data) re-rec-count)]

I am not looking for a discussion of the best way, but what is in Clojure that facilitates solving a problem like this.

share|improve this question
    
I'm not sure, but maybe this would be better at Code Review? codereview.stackexchange.com/questions –  FrustratedWithFormsDesigner Nov 8 '12 at 18:22
add comment

2 Answers

up vote 4 down vote accepted

Unless you're using multiple else statements, you can just chain the conditions together with an "and". In Clojure, "and" is a macro which turns its arguments into a sequence of nested if statements.

share|improve this answer
add comment

Monads is the answer to this, the Maybe monad to be precise.

There is at least one Clojure library for monads.

Monads have a reputation for being difficult to learn, but they're definitely worth it (and not that bad).

You might check some Haskell tutorials on monads too, as they're a bigger part of Haskell than Clojure.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.