dimanche 26 avril 2020

Simple flow control and variable binding in Clojure

I'm learning Clojure and working on a simple file parsing script.

I have a file in the form of:

pattern1
pattern2
pattern3
pattern1
pattern2
...

where each line has a few values (numbers) that I extract.

If I was to write this in Java for example, I would do something similar to:

Map<String, Integer> parse(String line) {
    //using Optional in this toy example, but could be an empty map or something else to
    //signal if first one was actually matched and the values are there
    Optional<Map<String, Integer>> firstMatched = matchFirst(line);
    if (firstMatched.isPresent()) {
        return firstMatched.get();
    }
    //...do the same for 2 remaining patterns
    //...
}

Now what would be a an elegant or idiomatic way to do something similar in Clojure?

I guess I can use cond, but since there's no binding in the test expression, I'll have to parse the line twice:

(defn parse
  [line]
  (cond
    (re-find #"pattern-1-regex" line) (re-find...)
    (re-find #"pattern-2-regex" line) (re-find...

I could also use if-let, but that will be a lot of nesting since there are 3 different options. Imagine with 7 different pattern how that would look like.

Any suggestions? Obviously Java solution is an imperative one and I can do a "return" whenever I want, so what would be the Clojure/FP way of dealing with this simple branching.

Aucun commentaire:

Enregistrer un commentaire