fix (defn get-if [m pred] (let [[match & more] (filter (comp pred key) m)] (if (and match (not more)) (val match))))
Apologies. On Sunday, October 1, 2017 at 11:44:27 PM UTC+2, Leon Grapenthin wrote: > > 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.