Are there variables in Clojure sequence comprehensions? - clojure

I'm reading Programming Clojure 2nd edition, and on page 49 it covers Clojure's for loop construct, which it says is actually a sequence comprehension.
The authors suggest the following code:
(defn indexed [coll] (map-indexed vector coll))
(defn index-filter [pred col]
(when pred
(for [[idx elt] (indexed col) :when (pred elt)] idx)))
(index-filter #{\a} "aba")
(0 2)
...is preferable to a Java-based imperative example, and the evidence given is that it "by using higher-order functions...the functional index-of-any avoids all need for variables."
What are "idx", "elt" if they are not variables? Do they mean variables besides the accumulators?
Also, why #{\a} instead of "a"?

pred is a function - #{\a} is a set containing the character a. In Clojure, a set is a function which returns true if its argument \a is contained by it. You could also use #(= % \a) or (fn [x] (= \a x)).
As the other answer implies, "no state was created in the making of this example." idx and elt function like variables, but are local only to the for sequence comprehension, so the code is more compact, not stateful, and arguably clearer (once you're used to sequence comprehensions, at least :-) ) -- perhaps the text is not optimally clear on this point.

There are no variables in functional languages. Actually, you need distinguish variable and value. idx it's just a name bound to concrete value, and you can not reassign it (but you can rebound it to another value).
First parameter of function index-filter is predicate, that means function that return true or false. #{\a} it's a data structure set, but it also can be treated like a function. If you pass element as argument to set function it returns this argument (like true) if element exists and nil (like false) otherwise. So you can think about this set predicate as anonymous function written in more understandable way #(contains? #{\a} %)

Related

Trying to get a lazy-contains? function in Clojure to return results consistant with contains? when dealing with a map

Here's a use of the standard 'contains?' function in Clojure-
(contains? {:state "active", :course_n "law", :course_i "C0"} :state)
and it returns the expected
true
I used the following
Clojure: Idiomatic way to call contains? on a lazy sequence
as a guide for building a lazy-contains? as this is what I need for my present use-case.
The problem I'm facing is that for a map these alternatives are not returning the same answer, giving either a false or a nil response. I've tried looking at the source for contains? and it's slow going trying to understand what's happening so I can correct the lazy-contains? appropriately (for the record Clojure is essentially my first programming language, and my exposure to Java is very limited).
Any thoughts or ideas on how I might approach this? I tried every variant on the linked question I could.
Thanks in advance.
Edited to remove the error pointed out by #amalloy.
I think your problem is with the way that maps present themselves as sequences.
Given
(def data {:state "active", :course_n "law", :course_i "C0"})
then
(seq data)
;([:state "active"] [:course_i "C0"] [:course_n "law"])
... a sequence of key-value pairs.
So if we define (following #chouser)
(defn lazy-contains? [coll x]
(some #(= x %) coll))
... then
(lazy-contains? data :state)
;nil
... a false result, whereas ...
(lazy-contains? data [:state "active"])
;true
This is what #Ankur was getting at, showing you a function treating a map as a sequence consistent with contains? on the map itself.
The standard contains? works with keyed/indexed collections - maps
or sets or vectors - where it tests for the presence of a key.
Our lazy-contains? works with anything sequable, including all the
standard collections, testing for the presence of a value.
Given the way that keyed/indexed collections present as sequences, these are bound to be inconsistent.
You can try the below implementation (for maps only):
(defn lazy-contains? [col key]
(some (fn [[k v]] (= k key)) col))
Remember, contains? is to check the existence of a key in a collection, in maps the key is obvious, in other supported collections (like vector) the key is the index.
A "lazy" implementation of contains? is undesirable where checking for presence
of a key in a hash-map or of a value in a set
(contains? #{:foo} :foo}) => true
(contains? {:foo :bar} :foo) => true
of an index of a vector array or string.
(contains? [:foo] 0) => true
(contains? (int-array 7) 6) => true
(contains? "foo" 2) => true
Quoting from the contains? docstring:
'contains?' operates constant or logarithmic time; it will not
perform a linear search for a value.
some is a tool for linear searching. When searching for an element in a set or vector, it can take the input sequence length times as long as contains? or longer in the worst case and will take more time than contains? in almost every case.
contains? can't be implemented "lazy" as it does not produce a sequence. However, some stops consuming a lazy sequence as soon as it has determined a return value.
(some zero? (range))
;; true
Notice that maps and sets are never sequential or lazy.

Clojure: Apply or to a list

This question similar to say, In clojure, how to apply 'and' to a list?, but solution doesn't apply to my question. every? function returns just a boolean value.
or is a macro, so this code is invalid:
(apply or [nil 10 20]) ; I want to get 10 here, as if 'or was a function.
Using not-every? I will get just boolean value, but I want to preserve semantics of or - the "true" element should be a value of the expression. What is idiomatic way to do this?
My idea so far:
(first (drop-while not [nil 10 20])) ; = 10
you might be able to use some for this:
(some identity [nil 10 20]) ; = 10
Note that this differs from or if it fails
(some identity [false]) ; = nil
(or false) ; = false
A simple macro:
(defmacro apply-or
[coll]
`(or ~#coll))
Or even more abstract
(defmacro apply-macro
[macro coll]
`(~macro ~#coll))
EDIT: Since you complained about that not working in runtime here comes a version of apply-macro that works in runtime. Compare it with answers posted here: In clojure, how to apply a macro to a list?
(defmacro apply-macro-in-runtime
[m c]
`(eval (concat '(~m) ~c)))
Notice that this version utilizes that parameters are passed unevaluated (m is not evaluated, if this was a function, it would throw because a macro doesn't have a value) it uses concat to build a list containing of a list with the quoted macro-name and whatever the evaluation of form c (for coll) returns so that c as (range 5) would be fully evaluated to the list that range returns. Finally it uses eval to evaluate the expression.
Clarification: That obviously uses eval which causes overhead. But notice that eval was also used in the answer linked above.
Also this does not work with large sequences due to the recursive definition of or. It is just good to know that it is possible.
Also for runtime sequences it makes obviously more sense to use some and every?.

What is convention for local vars that has same meaning as function argument?

What is convention for local vars that has same meaning as function argument?
If I need local variable that has as its initial state value of function argument (and thus has the same meaning), how should I call it?
As artificial example (that, however, demonstrates quite popular construction in Clojure):
(defn sum [coll]
(loop [local-coll coll, result 0]
(if (empty? local-coll)
result
(recur (rest local-coll) (+ (first local-coll) result)))))
Here local-coll is initialized to the value of coll initially, and it also holds this meaning during looping. local-coll is definitely not a good name for it, but what is?
In Haskell it is a good style to put quote (') to the end of variable/function name, e.g. var'. In Common Lisp sometimes I saw names ending with asterisk (*). Clojure has same notation for function that duplicate another function meaning but have a bit different semantics (e.g. list*). But this notation is also frequently used in docstrings to indicate that there may be several items of this type (e.g. (methodname [args*] body)* or (try expr* catch-clause* finally-clause?)) and thus can confuse when used for local var names.
Java interop also provides things like defn-, that is names ending with hyphen (-) to indicate private methods in generated classes. So it makes some sense to use hyphen for local (private for a function) variables too (though it seems a bit weird for me).
So, what the way should I go when naming my local variables with the same meaning as function argument?
I think it's fine to shadow the argument name when you don't need the original argument any more:
(defn sum [coll]
(loop [coll coll, result 0]
(if (empty? coll)
result
(recur (rest coll) (+ (first coll) result)))))
Other variations that I've seen are:
(loop [c colls] ...)
(loop [coll initial-coll] ...)
(loop [foo foo-coll] ...)
(loop [s specs] ...)

Why Clojure idiom prefer to return nil instead of empty list like Scheme?

From a comment on another question, someone is saying that Clojure idiom prefers to return nil rather than an empty list like in Scheme. Why is that?
Like,
(when (seq lat) ...)
instead of
(if (empty? lat)
'() ...)
I can think of a few reasons:
Logical distinction. In Clojure nil means nothing / absence of value. Whereas '() "the empty list is a value - it just happens to be a value that is an empty list. It's quite often conceptually and logically useful to distinguish between the two.
Fit with JVM - the JVM object model supports null references. And quite a lot of Java APIs return null to mean "nothing" or "value not found". So to ensure easy JVM interoperability, it makes sense for Clojure to use nil in a similar way.
Laziness - the logic here is quite complicated, but my understanding is that using nil for "no list" works better with Clojure's lazy sequences. As Clojure is a lazy functional programming language by default, it makes sense for this usage to be standard. See http://clojure.org/lazy for some extra explanation.
"Falsiness" - It's convenient to use nil to mean "nothing" and also to mean "false" when writing conditional code that examines collections - so you can write code like (if (some-map :some-key) ....) to test if a hashmap contains a value for a given key.
Performance - It's more efficient to test for nil than to examine a list to see if it empty... hence adopting this idiom as standard can lead to higher performance idiomatic code
Note that there are still some functions in Clojure that do return an empty list. An example is rest:
(rest [1])
=> ()
This question on rest vs. next goes into some detail of why this is.....
Also note that the union of collection types and nil form a monoid, with concatenation the monoid plus and nil the monoid zero. So nil keeps the empty list semantics under concatenation while also representing a false or "missing" value.
Python is another language where common monoid identities represent false values: 0, empty list, empty tuple.
From The Joy of Clojure
Because empty collections act like true in Boolean contexts, you need an idiom for testing whether there's anything in a collection to process. Thankfully, Clojure provides such a technique:
(seq [1 2 3])
;=> (1 2 3)
(seq [])
;=> nil
In other Lisps, like Common Lisp, the empty list is used to mean nil. This is known as nil punning and is only viable when the empty list is falsey. Returning nil here is clojure's way of reintroducing nil punning.
Since I wrote the comment I will write a answer. (The answer of skuro provides all information but maybe a too much)
First of all I think that more importend things should be in first.
seq is just what everybody uses most of the time but empty? is fine to its just (not (seq lat))
In Clojure '() is true, so normaly you want to return something thats false if the sequence is finished.
if you have only one importend branch in your if an the other returnes false/'() or something like that why should you write down that branch. when has only one branch this is spezially good if you want to have sideeffects. You don't have to use do.
See this example:
(if false
'()
(do (println 1)
(println 2)
(println 3)))
you can write
(when true
(println 1)
(println 2)
(println 3))
Not that diffrent but i think its better to read.
P.S.
Not that there are functions called if-not and when-not they are often better then (if (not true) ...)

What is the correct "clojure way" to check if a collection is non empty

I want to write a function that would return the boolean true if the given collection is not empty and false otherwise.
I could either do
defn ..
(boolean (seq coll))
or
defn ..
(not (empty? coll))
As I am new to clojure I was initially inclined to go with #2 (more readable), but the clojure api reference for empty? explicitly says use the idiom (seq coll) instead of (not (empty? coll)), maybe to avoid double negation.
I want to know what is the clojure way to check if a collection is non-empty and return a boolean true/false.
According to Joy of Clojure, nil punning with seq is idiomatic:
(defn print-seq [s]
(when (seq s)
(prn (first s))
(recur (rest s))))
"...the use of seq as a terminating condition is the idiomatic way to test whether a sequence is empty. If we tested [in the above example] just s instead of (seq s), then the terminating condition wouldn't occur even for empty collections..."
The passage from empty?'s docstring which you mentioned means in particular that such a nonempty? function should never be necessary, or even particularly useful, because seq can always stand in for it in Boolean contexts, which in pure Clojure code it can.
If you feel compelled to write such a function nonetheless, I'll say that I like the first approach better. empty? is built on seq anyway, so there's no avoiding calling it; just casting the result to Boolean seems cleaner than two trips through not. For other options, see e.g. nil?, false? (I still prefer the cast).
Incidentally, why do you want to write this...? For calling a Java method with a boolean argument perhaps? In that case, I think the cast would express the intention nicely.
Update: An example to illustrate the latter point:
A simple Java class:
public class Foo {
public static boolean foo(boolean arg) {
return !arg;
}
}
Some Clojure client code:
(Foo/foo nil)
; => NullPointerException
(Foo/foo (boolean nil))
; => true
In addition to Michal Marczyk's excellent answer, I'll point out that there is a specific not-empty function:
http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not-empty
but it doesn't do exactly what you ask for. (Though it will work in most situations).
Not-empty returns nil if the collection is empty, and the collection itself if the collection is not empty. For predicate tests, that will function well. If you actually need true and false values, then (not (empty? x)) is what you're after.
If you need a boolean, I think (comp not seq) has a nice ring to it.
Example usage:
((comp not seq) coll)
And if you need to store it as a fn for later:
(def not-empty' (comp not seq))