All the good feedback here had me thinking a lot... Especially Andy who
pushed me towards more abstraction.
I loved the idea of functions that return functions and researching all
this led me to embrace "partials".
Here is my current implementation of "quantize". It came out of a lot of
trial and errors (gotta love the REPL) and even though, it became more
concise,
- I think it can be improved
- I am wondering if I'm going too far. I'm worried that it makes the
function hard to understand for someone who would maintain it. I don't have
enough FP experience to get an idea whether this function is well written,
or if it's just impossible to understand. From an imperative programming
background, it is certainly impossible to understand.
(def inf Long/MAX_VALUE)
(defn quantize
"Given a collection of ordered numeric 'markers' such as [m n], given a
collection of values such as [a b c], returns a if x <= m, returns b if m < x
<= n, returns c if n < x This should work for any size collections, but the
values neeed to have one more element than the markers."
[x markers values]
(let
[f (partial (fn([%1 %2 %3] (cond (<= %1 %2) %3))) x)]
(first (filter #(not (nil? %))(map f (conj markers inf) values)))))
A few things I don't like:
- (conj markers inf) to artificially add an "infinite enough" value to my
"markers" collection so that it turns [120 150 165 180] into [120 150 165
180 <infinity>]. Too bad there is no "infinity" in Clojure.
- I hate the #(not (nil? %)) but I could not find a predicate such as
not-nil?
- I was not able to get (some) to work in this context so I used (first
(filter instead.
- I could probably make this more readable by applying the Clojure styling
guide (I will)
Any idea how I could improve this function further for more elegance and
clarity?
With this function working, I can stick it to some "foundation" library and
create a simpler "hr" library.
My "hr" library would contain:
(def hr-zones [:z1 :z2 :z3 :z4 :z5])
(defn get-hr-zone [hr-zones-def bpm]
(quantize bpm hr-zones-def hr-zones))
And then, my client application would have:
(def get-my-hr-zone
(partial get-hr-zone [120 150 165 180]))
(get-my-hr-zone 119)(get-my-hr-zone 120)(get-my-hr-zone 149)(get-my-hr-zone
150)(get-my-hr-zone 151)
BTW, thanks Andy for the tip about Pygments.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.