patternMinor
Clojure function greater than 10 SLOC
Viewed 0 times
clojureslocgreaterthanfunction
Problem
It has been mentioned in the Clojure Style guide to avoid functions longer than 10 SLOC but mine has more than 10 (47 to be exact).
The code is an web api implementation and follows like this:
```
(defn classify
"Sends a text to a classifier and returns a classification"
[keys texts classifier & user-name]
{:pre [(check-keys? keys)]}
(let [textbase64-tag (map #(make-xml-node :textBase64
{:id (str "Text" (str (index-of % texts)))}
(String. (encode (.getBytes %)) )) texts)
texts-tag (make-xml-node :texts {} textbase64-tag)
user-attribute (if (> (count user-name) 0)
{ :username (first user-name) })
classify-tag (if (= (count user-name) 0)
(map #(make-xml-node :classify
{:id (str "Classify" %)
:classifierName classifier
:textId (str "Text" %)
})
(range (count texts)))
(map #(make-xml-node :classify
{:id (str "Classify" %)
:classifierName classifier
:textId (str "Text" %)
:username (first user-name)})
(range (count texts))))
read-calls (make-xml-node :readCalls
{:readApiKey (keys :read-key)}
classify-tag)
uclassify-response (raw-post-request
(xml/emit-str
(xml-append-elements uclassify
(list texts-tag read-calls))))]
(if (check-response
(get-response uclassify-response))
The code is an web api implementation and follows like this:
```
(defn classify
"Sends a text to a classifier and returns a classification"
[keys texts classifier & user-name]
{:pre [(check-keys? keys)]}
(let [textbase64-tag (map #(make-xml-node :textBase64
{:id (str "Text" (str (index-of % texts)))}
(String. (encode (.getBytes %)) )) texts)
texts-tag (make-xml-node :texts {} textbase64-tag)
user-attribute (if (> (count user-name) 0)
{ :username (first user-name) })
classify-tag (if (= (count user-name) 0)
(map #(make-xml-node :classify
{:id (str "Classify" %)
:classifierName classifier
:textId (str "Text" %)
})
(range (count texts)))
(map #(make-xml-node :classify
{:id (str "Classify" %)
:classifierName classifier
:textId (str "Text" %)
:username (first user-name)})
(range (count texts))))
read-calls (make-xml-node :readCalls
{:readApiKey (keys :read-key)}
classify-tag)
uclassify-response (raw-post-request
(xml/emit-str
(xml-append-elements uclassify
(list texts-tag read-calls))))]
(if (check-response
(get-response uclassify-response))
Solution
There's value in factoring the logic out into one or more new functions, even if those functions are only used in a single place, because it can make the code easier to understand and modify.
In a situation like that (when the logic won't be used elsewhere) I often use
Here's the ClojureDocs page on
On the other hand, there's really no problem with having a top level function that's only used in one place. I like that
In a situation like that (when the logic won't be used elsewhere) I often use
letfn. The letfn could be either internal or external to the function itself but I see that as a purely stylistic decision.Here's the ClojureDocs page on
letfn. See Pedestal's dataflow logic for a few examples of letfn in use.On the other hand, there's really no problem with having a top level function that's only used in one place. I like that
letfn implicitly communicates the function's scope of relevance, but I don't think either way is objectively superior to the other.Context
StackExchange Code Review Q#30106, answer score: 3
Revisions (0)
No revisions yet.