1. In general this style of iteration is not idiomatic unless you are 
hunting performance or write sth. that simply can't be composed from core 
sequence library (s. b.). If you have to write this style, look at 
`when-first`, `seq`, `next`. Study implementation of core library.

More idiomatic implementation is

(defn get-if [m pred]
  (let [[match & more] (filter (comp pred key) m)]
    (if-not more (val match))))

2. Let bindings to prevent repeated evaluation are fine. 
3. First position is fine, but you should use loop/recur or an inner 
let-bound lambda instead of exposing found in the public API of the function
4. Again, look at core functions. Rich does naming very carefully and 
consistent. In (1) I called it pred, because its called pred in functions 
like filter or some.
5. See 1


On Sunday, October 1, 2017 at 11:11:55 PM UTC+2, Scott Barrett wrote:
>
> Clojure noob, here. I'm very excited to be learning about this language 
> and becoming a part of this community :) I'm writing a function that works 
> well, but seems just a bit wrong to me, stylistically speaking. I was 
> hoping I could get some guidance from you all.
>
> Here's the code:
>
> (defn get-if
>   "Gets the value of a map if exactly one key matches a predicate, 
> otherwise nil"
>   ([m predicate?] (get-if nil m predicate?))
>   ([found m predicate?]
>    (if-let [e (first m)]
>      (let [pred (predicate? (key e))]
>        (if (not (and pred found))
>          (recur (if pred (val e) found) (rest m) predicate?))
>      found))))
>
> This has gone through a few revisions to get it as concise as possible, 
> but here are my questions/remarks:
>
>    1. Is it idiomatic to use if-let to move through a collection the way 
>    I have? In my experience with lispy languages, recursion over sequences 
>    tend to take the form (if (null item) accumlated-value 
>    (recur-over-rest)). This if-let form turns that on its head, which 
>    looks a little backwards at first to me, but it saves a level of 
>    indentation which is generally preferable in my experience.
>    2. The main part of this code that's bugging me is the let form, which 
>    is a total hack to keep from testing (predicate? (key e)) twice. Even 
>    still, I have to test the truthiness of pred twice; once in the (not 
>    (and ...)) form and once again in the if of the recur form. I feel 
>    like a clever use of (and ...) or (or ...) would save me here, but I 
>    haven't come upon a solution using those forms yet.
>    3. In general, when using recursion and multiple arities to get a 
>    result, is there an order that is preferred for the extra recursion 
>    accumulation values? Here I have [m predicate?] and [found m 
>    predicate?] versions of the function, but after looking at it for so 
>    long I think it might be more natural to put found as the last argument, 
> as 
>    in [m predicate? found], but I'm wondering if there's a standard to 
>    follow with things like this.
>    4. When passing functions as arguments, as I have here with the 
>    predicate? function, is there a standard naming convention? I used a 
>    question mark here, but would predicate be preferable, or even simply f
>    ?
>    5. Is writing this function even necessary? I didn't see a function 
>    that serves the same purpose in the standard libraries, but I'm very new 
>    and could easily have missed something!
>    
> I know that's a lot to ask for such a short segment of code. Feel free to 
> answer as many/few of these questions as you'd like, as any help would be 
> greatly appreciated (though, if you're going to answer one, I think point 
> #2 is the most important) :)
>
>
> Thanks in advance, fellow clojurians!
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to