Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Are there more recent features of Clojure that you think have made every-pred and some-fn less useful? I'm curious what they are if that is the case.


So, for the every-pred example, I'd prefer to use clojure piping for better readability:

  (->> people (filter :admin?) (filter :mod?))
This is admittedly a matter of taste, though.

For the some-fn example, I would argue that the usage in OP is a very idealized and tuned example... how often do you really want to say "try this one predicate and if that doesn't work, try this other one"? I only need to do that maybe a couple of times a year (when parsing some sort of irregular raw data) so it's rare enough that I'd prefer to write the predicate explicitly instead of using this sort of succinct predicate composition that could become a "head-scratcher" at a future date.


If you’re going to do this, transducers let you avoid the intermediate sequences and are nearly just as readable:

    (into []
          (comp (filter :admin?)
                (filter :mod?))
          people)
As a side-effect, they are also more generic so you can reuse the transducer stack if you decide to use core.async or something.


So I find very few examples of people using transducers in production code these days. I agree they are very compelling from a theoretical programming standpoint, and I used them heavily for about a year for that reason. However, it clearly took me far longer to debug transducing code compared to traditional code, so these days I only use them when absolutely necessary for optimization purposes.


Interesting, I find the ergonomics of transducers a lot better than the threading macros, especially because it’s a more generic interface. Also, they seem to be an ideal point in the lazy/strict evaluation continuum: they compose like lazy functions (I.e. if you have (take 3), you’ll only get three elements even with an infinite input stream but they avoid the unpredictability of lazy functions like map because the actual process is run eagerly (unless this doesn’t make sense for the output datatype e.g. a core async channel.).

I’d also be a bit careful about judging popularity from open source codebases too: they are used heavily in all the production code based I maintain :) and I get the sense that they’re pretty widely used by the “silent majority” of clojure programmers.

My debugging strategy for them is basically what I do for threading macros anyways: (into [] (comp ... (map #(doto % (->> (println :it))) ....) inp)


Nice feature of doing it like in the post:

  (filter (every-pred :admin? :mod?) people)
is that a) this arguably conses less, by building only one results list, and b) :admin? and :mod? are just regular arguments, which means they could be replaced by data. I'm thinking of:

  (let [acl [:admin? :mod?]]
    (filter (apply every-pred acl) people))
This capitalizes on Clojure's interesting design decision in which when funcalled, a :keyword resolves to function that gets an element with the name :keyword from the map passed as the argument.


I admit a case can be made for having every-pred in the language, since from a mathematical standpoint predicate composition is an innate low-level feature (putting the questionable naming issue aside)


> this arguably conses less, by building only one results list

Aren't lazy sequences idiomatic in Clojure?


Vs:

    (filter (and| :admin? :mod?)
            people)
and:

    (filter (or| :admin? :mod?)
            people)


I agree something like that, with a more concise naming strategy, would be ideal.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: