Equivalent of every-pred, but for any of the given predicates - clojure

Any cuter way to express this?
#(or (:a %) (b: %) (:c %)) ;; would prefer (desired-fn :a :b :c)
clojure.core lacks a "any-pred" function, maybe because there is already a means of providing the same functionality? Or would have one to implement it himself?

some-fn is what you're looking for. The only difference is that some-fn will return false rather than nil in the case where none of the functions return a logically true value.
Just as a note on naming: it's not called "some-pred"/"any-pred" because predicates only return true or false, whereas some-fn will return the first logically true value (which may not be true itself).

Related

Idiomatic `and` & `or` functions (not macros) in Clojure

Strange as it may sound, I am looking for function versions of the and and or macros in Clojure.
Why? For one I am curious.
Second, I want to use or in precondition and postcondition checks. This does not work:
(defn victor
[x]
{:post (or (nil? %) (vector %))}
;; ...
)
I want the postcondition to check to see if victor returns a vector or nil, but it fails:
#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling:(test/test.clj:10:1)>
I don't think bit-and and bit-or are quite what I'm looking for.
Update: This syntax works without an error:
(defn victor
[x]
{:post [(or (nil? %) (vector %))]}
;; ...
)
I'm still curious if functions exist, though.
I think the standard method is simply to wrap and and or in functions, e.g. (fn [x y] (or x y)). In some contexts, another function will work. For example, a note in the clojure docs for and suggests using (every? identity [true false]). some, not-every?, and not-any? can be used in a similar way.
In general, and and or functions would be undesirable because they cannot use short-circuiting. Consider the following code:
(and false some-expensive-fn)
(or true some-expensive-fn)
With and and or as macros the above code won't execute some-expensive-fn, because it is unnecessary to determine the overall truth value of the expression. In function expressions the arguments are evaluated before being passed to the function, but in macros they are not.
#Triangle Man is right. Short-circuiting won't work, but nevertheless you can define your own function versions:
user=> (defn && [x y] (and x y))
#'user/&&
user=> (&& true false)
false
user=> (&& true true)
true
user=> (defn || [x y] (or x y))
#'user/||
user=> (|| true false)
true
user=> (|| true true)
true
user=> (|| false false)
false
user=>

In clojure, what is the exact behaviour of identical?

I am very surprised by the behaviour of identical? in clojure.
(def a (map identity [:a :b]))
(identical? (rest a) (rest a)); false
Any idea why identical? returns false?
identical?:
Tests if 2 arguments are the same object
Since rest creates a new seq object on each invocation, its results are not identical?. The following, however, is:
(def r (rest (map identity [:a :b])))
(identical? r r) ;; => true
Update: As #mfikes pointed out, rest does not always create a new seq. It calls ISeq.more() internally which is implemented per seq type and might yield different results for lists, vectors, lazy seqs, etc.:
(->> [(map identity [:a :b])
(vector :a :b)
(list :a :b)]
(map #(identical? (rest %) (rest %))))
;; => [false false true]
identical? is the object equality predicate. It returns true if its arguments are the same object/primitive.
Use = over identical?.
identical? is the correct tool when semantics depend on pointer equality, such as testing for an end-of-file sentinel value.
Never use identical? to compare Clojure data structures. Even keywords don't guarantee identical? behaves correctly.

what advantage is there to use 'get' instead to access a map

Following up from this question: Idiomatic clojure map lookup by keyword
Map access using clojure can be done in many ways.
(def m {:a 1}
(get m :a) ;; => 1
(:a m) ;; => 1
(m :a) ;; => 1
I know I use mainly the second form, and sometimes the third, rarely the first. what are the advantages (speed/composability) of using each?
get is useful when the map could be nil or not-a-map, and the key could be something non-callable (i.e. not a keyword)
(def m nil)
(def k "some-key")
(m k) => NullPointerException
(k m) => ClassCastException java.lang.String cannot be cast to clojure.lang.IFn
(get m k) => nil
(get m :foo :default) => :default
From the clojure web page we see that
Maps implement IFn, for invoke() of one argument (a key) with an
optional second argument (a default value), i.e. maps are functions of
their keys. nil keys and values are ok.
Sometimes it is rewarding to take a look under the hoods of Clojure. If you look up what invoke looks like in a map, you see this:
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L196
It apparently calls the valAt method of a map.
If you look at what the get function does when called with a map, this is a call to clojure.lang.RT.get, and this really boils down to the same call to valAt for a map (maps implement ILookUp because they are Associatives):
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L634.
The same is true for a map called with a key and a not-found-value. So, what is the advantage? Since both ways boil down to pretty much the same, performance wise I would say nothing. It's just syntactic convenience.
You can pass get to partial etc. to build up HOFs for messing with your data, though it doesn't come up often.
user=> (def data {"a" 1 :b 2})
#'user/data
user=> (map (partial get data) (keys data))
(1 2)
I use the third form a lot when the data has strings as keys
I don't think there is a speed difference, and even if that would be the case, that would be an implementation detail.
Personally I prefer the second option (:a m) because it sometimes makes code a bit easier on the eye. For example, I often have to iterate through a sequence of maps:
(def foo '({:a 1} {:a 2} {:a 3}))
If I want to filter all values of :a I can now use:
(map :a foo)
Instead of
(map #(get % :a) foo)
or
(map #(% :a) foo)
Of course this is a matter of personal taste.
To add to the list, get is also useful when using the threading macro -> and you need to access via a key that is not a keyword
(let [m {"a" :a}]
(-> m
(get "a")))
One advantage of using the keyword first approach is it is the most concise way of accessing the value with a forgiving behavior in the case the map is nil.

Clojure koans: (if false []) vs (if false [:a :b :c])

I've started learning Clojure this week. I'm working my way through the conditional koans and don't understand the following assertions:
"Some of them leave you no alternative"
(= [] (if (> 4 3)
[]))
"And in such a situation you may have nothing"
(= nil (if (nil? 0)
[:a :b :c]))
The second one does what I would expect -- the condition evaluates to false-- [EDIT: Actually, it's true and I'm just still not used to 'operator-first' reasoning!], if tries to return the second alternative, finds none, and so returns nil. So, why doesn't the first return nil? Is it because an empty structure is 'close enough' to nil?
Because the first if evaluates to true (as 4 is indeed greater than 3), so else-clause is irrelevant. It returns the then-clause, which is defined and equal to [].

Clojure does not have !=?

Does not exist?
Does exist:
Clojure 1.2.0
user=> (not= 1 2)
true
user=> (not= 1 1)
false
user=> (doc not=)
-------------------------
clojure.core/not=
([x] [x y] [x y & more])
Same as (not (= obj1 obj2))
nil
Amusingly, you could define != to be the same as not= if you really wanted:
user=> (def != not=)
#'user/!=
user=> (!= 2 2)
false
user=> (!= 2 3)
true
In a lot of clojure code the ! char means that a function changes the state of something in a way you should watch out for. the clojure transients make heavy use of these
compare-and-set!
alter-meta!
conj!
persistent!
check out http://clojure.github.com/clojure/ and search for the ! character. these functions usually come with caveats like "must be free of side effects"
According to my google search "not=" is the equivalent but I have zero personal familiarity with Clojure.
Is there some reason not= doesn't suit your purposes?