Why the difference in anonymous function definition syntax? - clojure

We can define and use an anonymous function like this:
repl=> (#(+ 10 %) 1)
11
But -> macro won't accept such anonymous functions. Say I want to add 10 and then multiply by 2. I'd try to write:
(-> 5 #(+ 10 %) #(* 2 %))
But that is not the correct code for some reason, the correct code is
(-> 5 (+ 10) (* 2))
What is the difference between (+ 10) and #(+ 10 %), and why won't -> macro accept anonymous functions defined with #()?

Here's my attempt at an explanation. There are two parts.
First, the anonymous literal syntax. When you write #(+ 10 %), it gets expanded into something that is functionally similar to the following:
(fn [x] (+ 10 x))
For ex.
=> (macroexpand '(#(+ 10 %))
Would return something like:
(fn* [p1__7230#] (+ 10 p1__7230#))
The second part. When you use the threading macro, as the docs say, the macro expands by inserting the first argument as the second item into the first form. And if there are more forms, inserts the first form as the second item in second form, and so on.
The key term here is second item. It doesn't care about what forms you are providing as arguments, it will just do an expansion using that rule.
So, to combine both the points, when you use
(-> 5 #(+ 10 %) #(* 2 %))
following the rules, it gets expanded into something that is functionally similar to this
(fn (fn 5 [x] (+ 10 x)) [y] (* 2 y))
which doesn't compile.
Also, as a side note, the form (+ 10) is not an anonymous function. It is a partial function call that gets updated with arguments during macro expansion. And by 'partial', I mean in the literal sense, not in the functional programming sense.
Update
To explain why it works when you enclose the anonymous literal within parentheses (as a comment on the question says), you can infer the results from these two rules. For ex.
=> (macroexpand '(#(+ 10 %)))
would result in the functional equivalent of
((fn [x] (+ 10 x)))
So, when an item is inserted in its second place, it would look like
((fn [x] (+ 10 x)) 5)
Which is equivalent to
(#(+ 10 %) 5)

Related

How do I evaluate the first step of a Clojure form?

If I have the following string containing a valid Clojure/ClojureScript form:
"(+ 1 (+ 2 (/ 6 3)))"
How would I evaluate the first "step" of this form? In other words, how would I turn the above form into this:
"(+ 1 (+ 2 2))"
and then turn that corresponding form into this:
"(+ 1 4)"
You use recursion.
You need to have a function that evaluates the numbers to themselves but if it's not a number you need to apply the operation on the evaluation of the arguments.. Thus
(evaluate '(+ 1 (+ 2 (/ 6 3))))
This should be treated as:
(+ (evaluate '1) (evaluate '(+ 2 (/ 6 3))))
When it starts doing your first step several steps are waiting for the results to be done as well.
Note I'm using list structure and not strings. With strings you would need to use some function to get it parsed.
The other answers are great if you want to execute code in steps, but I want to mention that this evaluation can also be visualized using a debugger. See below Cider's debugger in action:
By using cider-debug-defun-at-point we add a breakpoint on evaluate. Then when the evaluate definition is evaluated the breakpoint is hit, and we step through the code by pressing next repeatedly.
A debugger is very handy when you want to evaluate "steps" of forms.
Below is a very basic implementation that does what you're looking for. It would be more common to eval the entire form, but since you're wanting to just simplify the innermost expressions, this does it:
(defn leaf?
[x]
(and (list? x)
(symbol? (first x))
(not-any? list? (rest x))))
(defn eval-one
[expr]
(cond
(leaf? expr) (apply (-> (first expr) resolve var-get)
(rest expr))
(list? expr) (apply list (map eval-one expr))
:default expr
))
(read-string "(+ 1 (+ 2 (/ 6 3)))")
=> (+ 1 (+ 2 (/ 6 3)))
(eval-one *1)
=> (+ 1 (+ 2 2))
(eval-one *1)
=> (+ 1 4)
(eval-one *1)
=> 5
This is naive and for illustrative purposes only, so please don't be under the impression that a real eval would work this way.
We define a leaf as a list whose first element is a symbol and which does not contain any other lists which could be evaluated. We then process the form, evaluating leaf expressions, recursively evaluating non-leaf expressions which are lists, and for anything else, we just insert it into the resulting expression. The result is that all innermost expressions which can be evaluated, according to our definition, are evaluated.
To add to the other great answers, here is a simple function that should return the first form to evaluate in a given string:
(defn first-eval [form-str]
(let [form (read-string form-str)
tree-s (tree-seq sequential? identity form)]
(first (filter #(= % (flatten %)) tree-s))))
Usage:
(first-eval "(+ 1 (+ 2 (/ 6 3)))") ;; returns (/ 6 3)
tree-seq is fairly limited in it's ability to evalute ALL form, but it's a start.

Clojure filter composition with reduce

I have a higher order predicate
(defn not-factor-of-x? [x]
(fn [n]
(cond
(= n x) true
(zero? (rem n x)) false
:else true)))
which returns a predicate that checks if the given argument n is not a factor of x.
Now I want to filter a list of numbers and find which are not factors of say '(2 3). One way to do this would be :
(filter (not-factor-of-x? 3) (filter (not-factor-of-x? 2) (range 2 100)))
But one can only type so much. In order to do this dynamically I tried function composition :
(comp (partial filter (not-factor-of-x? 2)) (partial filter (not-factor-of-x? 3)))
And it works. So I tried reducing the filters, like this:
(defn compose-filters [fn1 fn2]
(comp (partial filter fn1) (partial filter fn2)))
(def composed-filter (reduce compose-filters (map not-factor-of-x? '(2 3 5 7 11))))
(composed-filter (range 2 122)) ; returns (2 3 4 5 6 7 8 9 10 .......)
So, why the filter composition is not working as intended ?
There are many ways to compose functions and/or improve your code. Here's one:
(defn factor? [n x]
(and (not= n x) (zero? (rem n x))))
(->> (range 2 100)
(remove #(factor? % 2))
(remove #(factor? % 3)))
;; the same as the above
(->> (range 2 100)
(remove (fn [n] (some #(factor? n %) [2 3]))))
To see your problem with (reduce compose-filters ... let's look a bit at what that actually does. First, it uses filter on the first two predicates and composes them.. The result of that is a new function from sequences to sequences. The next iteration then calls filter on that function, when filter expects a predicate. Every sequence is a truthy value, so that new filter will now never remove any values because it's using a "predicate" which always returns truthy values. So in the end, only the very last filter actually does any filtering - in my REPL your code removes the numbers 22, 33, 44 and so on because 11 is a factor in them. I think the reduce you want to do here is more like
(reduce comp (map (comp (partial partial filter) not-factor-of-x?) '(2 3 5 7 11)))
Note how because we only want to call (partial filter) once per number, you can move that into the mapping step of the mapreduce. As to how I'd do this, considering that you produce all your predicates together:
(map not-factor-of-x? '(2 3 5 7 11))
it seems more natural to me to just combine the predicates at that point using every-pred
(apply every-pred (map not-factor-of-x? '(2 3 5 7 11)))
and use one filter on that predicate. It seems to communicate the intent a little more clearly ("I want values satisfying every one of these preds") and unlike composition of (partial filter ...) it avoids making an intermediate sequence for each predicate.
(In Clojure 1.7+ you can also avoid this by composing the transducer version of filter).

Variadic function with keyword arguments

I'm a newbie to Clojure and I was wondering if there is a way to define a function that can be called like this:
(strange-adder 1 2 3 :strange true)
That is, a function that can receive a variable number of ints and a keyword argument.
I know that I can define a function with keyword arguments this way:
(defn strange-adder
[a b c & {:keys [strange]}]
(println strange)
(+ a b c))
But now my function can only receive a fixed number of ints.
Is there a way to use both styles at the same time?
unfortunately, no.
The & destructuring operator uses everything after it on the argument list so it does not have the ability to handle two diferent sets of variable arity destructuring groups in one form.
one option is to break the function up into several arities. Though this only works if you can arrange it so only one of them is variadic (uses &). A more universal and less convenient solution is to treat the entire argument list as one variadic form, and pick the numbers off the start of it manually.
user> (defn strange-adder
[& args]
(let [nums (take-while number? args)
opts (apply hash-map (drop-while number? args))
strange (:strange opts)]
(println strange)
(apply + nums)))
#'user/strange-adder
user> (strange-adder 1 2 3 4 :strange 4)
4
10
Move the variadic portion to the the tail of the argument list and pass the options as a map:
(defn strange-adder [{:keys [strange]} & nums]
(println strange)
(apply + nums))
(strange-adder {:strange true} 1 2 3 4 5)
There is no formal support that I know of, but something like this should be doable:
(defn strange-adder
[& args]
(if (#{:strange} (-> args butlast last))
(do (println (last args))
(apply + (drop-last 2 args)))
(apply + args)))
I don't know if this can be generalized (check for keywords? how to expand to an arbitrary number of final arguments?). One option may be putting all options in a hashmap as the final argument, and checking if the last argument is a hashmap (but this would not work for some functions that expect arbitrary arguments that could be hashmaps).

How To Define Function From Closure

This question is related to one I asked recently.
If I rewrite (fn [n] (fn [x] (apply * (repeat n x)))) as
(defn power [n] (fn [x] (apply * (repeat n x))))`
it works just fine when used like this
((power 2) 16)
I can substitute 2 with another power, but I'd like to make a function just for squares, cubed, and so on. What is the best way to do that? I've been fiddling with it in the REPL, but no luck so far.
Using a macro for this goes entirely around his question, which was "I have a function that generates closures, how do I give those closures names?" The simple solution is:
(letfn [(power [n]
(fn [x]
(apply * (repeat n x))))]
(def square (power 2))
(def cube (power 3)))
If you really truly hate repeating def and power a few times, then and only then is it time to get macros involved. But the amount of effort you'll spend on even the simplest macro will be wasted unless you're defining functions up to at least the tenth power, compared to the simplicity of doing it with functions.
Not quite sure if this is what you're searching for, but macro templates might be it. Here's how I would write your code:
(use 'clojure.template)
(do-template [name n]
(defn name [x] (apply * (repeat n x)))
square 2
cube 3)
user> (cube 3)
;=> 27
For more complex type of similar tasks, you could write a macro that wrap do-template to perform some transformation on its arguments, e.g.:
(defmacro def-powers-of [& ns]
(let [->name #(->> % (str "power") symbol)]
`(do-template [~'name ~'n]
(defn ~'name [~'x] (apply * (repeat ~'n ~'x)))
~#(->> ns
(map #(vector (->name %) %))
flatten))))
(def-powers-of 2 3 4 5)
user> (power3 3)
;=> 27
user> (power5 3)
;=> 243
P.S.: That macro might look awkward if you're just starting with Clojure though, don't give up because of it! ;-)

swap! alter and alike

I am having a problem understanding how these functions update the underlying ref, atom etc.
The docs say:
(apply f current-value-of-identity args)
(def one (atom 0))
(swap! one inc) ;; => 1
So I am wondering how it got "expanded" to the apply form. It's not mentioned what exactly 'args' in the apply form is. Is it a sequence of arguments or are these separate values?
Was it "expanded" to:
(apply inc 0) ; obviously this wouldnt work, so that leaves only one possibility
(apply inc 0 '())
(swap! one + 1 2 3) ;; #=> 7
Was it:
(apply + 1 1 2 3 '()) ;or
(apply + 1 [1 2 3])
(def two (atom []))
(swap! two conj 10 20) ;; #=> [10 20]
Was it:
(apply conj [] [10 20]) ;or
(apply conj [] 10 20 '())
The passage you quoted from swap!'s docstring means that what happens is the equivalent of swapping in a new value for the Atom obtained from the old one with (apply f old-value args), where args is a seq of all additional arguments passed to swap!.
What actually happens is different, but that's just an implementation detail. For the sake of curiosity: Atoms have a Java method called swap, which is overloaded to take from one to four arguments. The first one is always an IFn (the f passed to swap!); the second and third, in present, are the first two extra arguments to that IFn; the fourth, if present, is an ISeq of extra arguments beyond the first two. apply is never involved and the fixed arity cases don't even call the IFn's applyTo method (they just use invoke). This improves performance in the common case where not too many extra arguments are passed to swap!.