Destructuring function arguments in Clojure - clojure

I'm running an example in Clojure Programming by Chas Emerick et al.:
(defn make-user
[& [uid]]
{:user-id (or uid (str (java.util.UUID/randomUUID)))})
output:
=> (make-user "T-800")
{:user-id "T-800"}
Now I remove the square brackets around uid in line 2:
(defn make-user
[& uid]
{:user-id (or uid (str (java.util.UUID/randomUUID)))})
The evaluation result becomes:
=> (make-user "T-800")
{:user-id ("T-800")}
How to understand this difference?

In an argument declaration, putting arguments next to & causes them to get wraped into a list.
(defn return [x y & more]
[x y more])
(return 1 2 3 4 5 6)
;=> [1 2 (3 4 5 6)]
This wraping is useful to manipulate an undetermined number of args in a function:
(defn plus [& more] (apply + more))
(plus 3 4)
;=> 7
(plus 3 4 5 6)
;=> 18
But if we know there will only be one element as the optional argument and want to directly access it, we could use first to extract it:
(defn make-user-1 [& uid] {:user-id (first uid)})
(make-user-1 "T-800")
;=> {:user-id "T-800"}
Or, we could simply unwrap the argument element by using destructuring!
(defn make-user-2 [& [uid]] {:user-id uid})
(make-user-2 "T-800")
;=> {:user-id "T-800"}
So, here are some arg declaration and their given output:
(defn f [arg] arg) ;=> arg
(defn f [& arg] arg) ;=> (arg)
(defn f [& [arg]] arg) ;=> arg
The more you wrap args in the arg declaration, the more those unwrap in the body.

[& uid]:
& means putting all arguments together as a list named uid.
So, uid here is of type list
[& [uid]]:
putting all arguments together as [uid], which is a list (not because [] but it is after &).
In addition, do a destructuring of this list by grabbing the first element as uid
So uid here is not a list but just one element.

Related

Function composition with variable function arguments

I am currently struggling with an assignment to create an anonymous function, in order to fulfil the following test cases:
Test case 1:
(= [3 2 1] ((__ rest reverse) [1 2 3 4]))
Test case 2:
(= 5 ((__ (partial + 3) second) [1 2 3 4]))
Test case 3:
(= true ((__ zero? #(mod % 8) +) 3 5 7 9))
Test case 4:
(= "HELLO" ((__ #(.toUpperCase %) #(apply str %) take) 5 "hello world"))
I came up with the solution:
(fn [& fs]
(fn [& items] (reduce #(%2 %1)
(flatten items)
(reverse fs))))
My idea was to create a list of the functions bound to the outer function, and then to apply a reducer on this function list, beginning with array "items".
As this works fine for chaining single arity functions in test cases 1 and 2, I have no idea how to modify the inner Lambda-function, in order to deal with multi-arity functions:
(apply + ___ ) ;; first function argument of test case 3
(take 5 ___ ) ;; first function argument of test case 4
Is there still a way to get around this problem?
Many thanks!
Source:
4Clojure - Problem 58
Addendum: I came across a "funky" solution using:
(fn [& fs] (reduce (fn [f g] #(f (apply g %&))) fs))
I don't fully understand this approach, to be honest...
Addendum 2: There was a similar discussion on this topic 7 years ago:
Clojure: Implementing the comp function
There I found the following solution:
(fn [& xs]
(fn [& ys]
(reduce #(%2 %1)
(apply (last xs) ys) (rest (reverse xs)))))
However, I still do not understand how we are able to kick off the reducer on the expression (apply (last xs) ys) , which represents the left-most function in the function chain.
In test case 1, that would translate to (apply rest [1 2 3 4]), which is wrong.
This is very similar to how comp is implemented in clojure.core.
(defn my-comp
([f] f)
([f g]
(fn
([] (f (g)))
([x] (f (g x)))
([x y] (f (g x y)))
([x y & args] (f (apply g x y args)))))
([f g & fs]
(reduce my-comp (list* f g fs))))
The key to understanding higher order function like comp is to think about what needs to happen when we compose functions.
What is the simplest case ? (comp f) Comp only receiving a single function, so we just return that function, there is no composition yet. How about second most simple case: Comp receiving two functions, like (comp f g), now we need to return another function which when called, does the composition, like (f (g)). But this returned function needs to support zero or more arguments, so we make it variadic. Why does it need to support zero or more arguments ? Because of function g, the inner most function can have zero or more arguments.
For example: what does (comp dec inc) return ?
It returns this fn:
(fn
([] (dec (inc)))
([x] (dec (inc x)))
([x y] (dec (inc x y)))
([x y & args] (dec (apply inc x y args)))))
It assumes that inc (the inner most function which gets executed first) could receive zero or more args. But in reality inc only supports one argument, so you would get the arity exception if you called this function with more than one argument like this ((comp dec inc) 1 2), but calling it with single argument would work, because the inner most function inc has a single arity, ((comp dec inc) 10). I hope I am clear here, why this returned function needs to be variadic.
Now for the next step, what if we compose three or more functions ? This is simple now, because the bread and butter was already implemented with two argument function that my-comp supports. So we just call this 2 argument function while we reduce through a list of supplied functions. Each step returns a new function which wraps the input function.
The first two test cases have the rest params: [[1 2 3 4]], not [1 2 3 4].
So it's not (apply rest [1 2 3 4]) but (apply rest [[1 2 3 4]]) or (rest [1 2 3 4]).
To drill it home:
(rest-ex [& rst]
rst
)
(rst 1 2 3) ;;=> [1 2 3]
(rst [1 2] 3) ;;=> [[1 2] 3]
(rst [1 2 3]) ;;=> [[1 2 3]]
Using apply:
; rest example one
(apply + [1 2 3]) ;;=> 6
; rest example two
(apply conj [[1 2] 3]) ;;=> [1 2 3]
; rest example three
(apply reverse [[1 2 3]]) ;;=> (3 2 1)
For both your funky solution and comp itself, it's like taking a car (the first function), beefing it up with a turbo, installing speakers (the following function). The car, w/ the turbo and amazing sound system, is available for the next group of friends to use (the apply turns it from a one-seat stock car to having as many "seats" as you want). In your case, the reducer function uses apply w/ a rest parameter, so it's like offering the option for more doors w/ each function added (but it chooses one door anyway).
The first two test cases are simple, and reduce isn't needed but can be used.
;; [[1 2 3 4]]
;; [rest reverse]
((fn [& fs] (reduce (fn [f g] #(f (apply g %&))) fs)) rest reverse) ;; is functionally equivalent to
((fn [& fs] #((first fs) (apply (second fs) %&))) rest reverse)
#(rest (apply reverse %&))
;; So
(((fn [& fs] (reduce (fn [f g] #(f (apply g %&))) fs)) rest reverse) [1 2 3 4]) ;; (3 2 1)
(((fn [& fs] #((first fs) (apply (second fs) %&))) rest reverse) [1 2 3 4]) ;; (3 2)
(#(rest (apply reverse %&)) [1 2 3 4]) ;;=> (3 2 1)
The third test case, on the second round of reduce, after it's started, looks like:
;; [3 5 7 9]
;; [zero? #(mod % 8) +]
;; ^ ^ The reducer function runs against these two f's
;; Which turns the original:
(fn [& fs] (reduce (fn [f g] #(f (apply g %&))) fs))
;; into an equivalent:
(reduce #(zero? (apply (fn [v] (mod v 8)) [g])) [+])
;; which ultimately results in (wow!):
((fn [& args] (zero? (apply (fn [v] (mod v 8)) [(apply + args)]))) 3 5 7 9)
Pay careful attention to the %& in the reducer function. that's why I wrapped (apply + args) in a vector.
While going through this, I realized what I intuited from my use of reduce is a tiny bit more involved than I realized--esp. w/ function composition, rest params, and apply at play.
It's not that simple, but it's understandable.

Interpreting `(apply partial partial args)` in Clojure?

I have faux-curry in Programming Clojure book.
user=> (defn faux-curry [& args] (apply partial partial args))
#'user/faux-curry
user=> (def add-3 ((faux-curry +) 3))
#'user/add-3
user=> (add-3 10)
13
However, it's hard to see why two partials are needed in the body.
In Coluredocs.org, I see (apply f args) as an example of an apply function. How to interpret (apply partial partial args)?
I think the easiest way to understand this is to expand out each part.
(partial + 2) returns a function
(fn [& xs] (apply + 2 xs))
calling the resulting function calls + with 1 and all the subsequent args passed to partial.
(apply + 2 [3 4 5]) is the same as (+ 2 3 4 5)
(fn [& xs] ...) says "take a sequence of arguments and call them xs"
which is like (fn [x1 x2 x3...] ...)
(partial partial) returns a function
(fn [& xs] (apply partial xs))
which has exactly the same behavior as partial because the function it produces just directly calls partial with all the arguments.
(apply partial partial args)
is the same as
(partial partial arg1 arg2...)
returns
(fn [& xs] (apply partial arg1 arg2... xs))
(apply partial partial [+ 1]) produces
(fn [& xs] (apply partial + 1 xs)).
Let's call this result g.
(g 2) => (apply partial + 1 [2]) => (fn [& xs] (apply + 1 2 xs)). Let's call this result h. (h 4 5) => (apply + 1 2 [4 5]) => (+ 1 2 4 5)
But if you were to leave out one of the partials:
(apply partial [+ 1]) produces
(fn [& xs] (apply + 1 xs)))
calling this resultant function will not return a function, but the result of summing the arguments with 1.
So having observed these behaviors, let's attempt to describe
(apply partial partial args):
"Create a function that creates a function that applies some function with the supplied arguments at creation time, and the supplied arguments at call time."
Hence faux-curry is a function that creates a function that creates a function o_O

misunderstanding of variable arguments type

I am trying to solve a clojure problem where I implement my own comp function.
I have the following expression that works how I expect:
(reduce #(apply %2 [%1]) [1 2 3 4] [rest reverse])
This gives an output of
(4 3 2)
I have tried abstracting this into a function like this:
(((fn [& funcs]
(fn [& args]
(reduce #(apply %2 [%1]) args funcs)
)) rest reverse) [1 2 3 4])
But I get the following error when I run it:
CompilerException java.lang.ClassCastException: clojure.lang.ArraySeq
cannot be cast to java.lang.Number,
compiling:(/Users/paulcowan/projects/scratch/src/scratch/core.clj:1:1)
To me the only difference that I can see is how that funcs and args are different types than the vectors that I created in the first example.
Why does reduce and apply behave differently in the second example?
Simply:
(defn my-comp [& fns]
(fn [x] (reduce #(%2 %1) x fns)))
giving
((my-comp rest reverse) [1 2 3 4])
;(4 3 2)
As it should, my-comp returns an identity function for an empty argument list.
But it expects all functions, including the first applied,
to take a single argument.
To get round (2), adapt it as follows:
(defn my-comp [& fns]
(if (empty? fns)
identity
(let [[f & fs] fns]
(fn [& args] (reduce #(%2 %1) (apply f args) fs)))))
Apart from (1), this merely rephrases Mark's answer.
For fun ...
We could define my-comp in terms of the standard comp:
(defn my-comp [& fns] (apply comp (reverse fns)))
But it probably makes more sense the other way round, since comp has to reverse its argument list in general:
(defn comp [& fns] (apply my-comp (reverse fns)))
We could even define an argument reverser
(defn rev-args [f] (fn [& args] (apply f (reverse args))))
... which turns a function into one that does the same thing to a reversed argument list.
Then
(def comp (rev-args my-comp))
or vice-versa:
(def my-comp (rev-args comp))
First of all, I don't get any error messages (nor correct result):
user> (((fn [& funcs]
(fn [& args]
(reduce #(apply %2 [%1]) args funcs))) rest reverse) [1 2 3 4])
;; => ()
Difference between the two examples is that in the first one you pass value [1 2 3 4] into reduce, while in the second one you pass [[1 2 3 4]] (because args is meant to keep all arguments of the function as one vector.
This will work:
user> (((fn [& funcs]
(fn [args]
(reduce #(apply %2 [%1]) args funcs))) rest reverse) [1 2 3 4])
;; => (4 3 2)
However, to get a function for functional composition that will be able to take any number of arguments, you should write something like this:
user> (defn my-comp [& fncs]
(fn [& args]
(reduce #(%2 %1) ; you can omit apply here, as %2 is already function
; and %1 is always one value, as noisesmith noticed
(apply (first fncs) args)
(rest fncs))))
;; => #'user/my-comp
user> (def my-fnc (my-comp rest reverse))
;; => #'user/my-fnc
user> (my-fnc [1 2 3 4])
;; => (4 3 2)
It will work fine, because only first function should have ability to take many arguments, as others will be applied to value returned by previously called function.

Clojure: Implementing the comp function

4Clojure Problem 58 is stated as:
Write a function which allows you to create function compositions. The parameter list should take a variable number of functions, and create a function applies them from right-to-left.
(= [3 2 1] ((__ rest reverse) [1 2 3 4]))
(= 5 ((__ (partial + 3) second) [1 2 3 4]))
(= true ((__ zero? #(mod % 8) +) 3 5 7 9))
(= "HELLO" ((__ #(.toUpperCase %) #(apply str %) take) 5 "hello world"))
Here __ should be replaced by the solution.
In this problem the function comp should not be employed.
A solution I found is:
(fn [& xs]
(fn [& ys]
(reduce #(%2 %1)
(apply (last xs) ys) (rest (reverse xs)))))
It works. But I don't really understand how the reduce works here. How does it represent (apply f_1 (apply f_2 ...(apply f_n-1 (apply f_n args))...)?
Let's try modifying that solution in 3 stages. Stay with each for a while and see if you get it. Stop if and when you do lest I confuse you more.
First, let's have more descriptive names
(defn my-comp [& fns]
(fn [& args]
(reduce (fn [result-so-far next-fn] (next-fn result-so-far))
(apply (last fns) args) (rest (reverse fns)))))
then factor up some
(defn my-comp [& fns]
(fn [& args]
(let [ordered-fns (reverse fns)
first-result (apply (first ordered-fns) args)
remaining-fns (rest ordered-fns)]
(reduce
(fn [result-so-far next-fn] (next-fn result-so-far))
first-result
remaining-fns))))
next replace reduce with a loop which does the same
(defn my-comp [& fns]
(fn [& args]
(let [ordered-fns (reverse fns)
first-result (apply (first ordered-fns) args)]
(loop [result-so-far first-result, remaining-fns (rest ordered-fns)]
(if (empty? remaining-fns)
result-so-far
(let [next-fn (first remaining-fns)]
(recur (next-fn result-so-far), (rest remaining-fns))))))))
My solution was:
(fn [& fs]
(reduce (fn [f g]
#(f (apply g %&))) fs))
Lets try that for:
((
(fn [& fs]
(reduce (fn [f g]
#(f (apply g %&))) fs))
#(.toUpperCase %)
#(apply str %)
take)
5 "hello world"))
fs is a list of the functions:
#(.toUpperCase %)
#(apply str %)
take
The first time through the reduce, we set
f <--- #(.toUpperCase %)
g <--- #(apply str %)
We create an anonymous function, and assign this to the reduce function's accumulator.
#(f (apply g %&)) <---- uppercase the result of apply str
Next time through the reduce, we set
f <--- uppercase the result of apply str
g <--- take
Again we create a new anonymous function, and assign this to the reduce function's accumulator.
#(f (apply g %&)) <---- uppercase composed with apply str composed with take
fs is now empty, so this anonymous function is returned from reduce.
This function is passed 5 and "hello world"
The anonymous function then:
Does take 5 "hello world" to become (\h \e \l \l \o)
Does apply str to become "hello"
Does toUppercase to become "HELLO"
Here's an elegent (in my opinion) definition of comp:
(defn comp [& fs]
(reduce (fn [result f]
(fn [& args]
(result (apply f args))))
identity
fs))
The nested anonymous functions might make it hard to read at first, so let's try to address that by pulling them out and giving them a name.
(defn chain [f g]
(fn [& args]
(f (apply g args))))
This function chain is just like comp except that it only accepts two arguments.
((chain inc inc) 1) ;=> 3
((chain rest reverse) [1 2 3 4]) ;=> (3 2 1)
((chain inc inc inc) 1) ;=> ArityException
The definition of comp atop chain is very simple and helps isolate what reduce is bringing to the show.
(defn comp [& fs]
(reduce chain identity fs))
It chains together the first two functions, the result of which is a function. It then chains that function with the next, and so on.
So using your last example:
((comp #(.toUpperCase %) #(apply str %) take) 5 "hello world") ;=> "HELLO"
The equivalent only using chain (no reduce) is:
((chain identity
(chain (chain #(.toUpperCase %)
#(apply str %))
take))
5 "hello world")
;=> "HELLO"
At a fundamental level, reduce is about iteration. Here's what an implementation in an imperative style might look like (ignoring the possibility of multiple arities, as Clojure's version supports):
def reduce(f, init, seq):
result = init
for item in seq:
result = f(result, item)
return result
It's just capturing the pattern of iterating over a sequence and accumulating a result. I think reduce has a sort of mystique around it which can actually make it much harder to understand than it needs to be, but if you just break it down you'll definitely get it (and probably be surprised how often you find it useful).
Here is my solution:
(defn my-comp
([] identity)
([f] f)
([f & r]
(fn [& args]
(f (apply (apply my-comp r) args)))))
I like A. Webb's solution better, though it does not behave exactly like comp because it does not return identity when called without any arguments. Simply adding a zero-arity body would fix that issue though.
Consider this example:
(def c (comp f1 ... fn-1 fn))
(c p1 p2 ... pm)
When c is called:
first comp's rightmost parameter fn is applied to the p* parameters ;
then fn-1 is applied to the result of the previous step ;
(...)
then f1 is applied to the result of the previous step, and its result is returned
Your sample solution does exactly the same.
first the rightmost parameter (last xs) is applied to the ys parameters:
(apply (last xs) ys)
the remaining parameters are reversed to be fed to reduce:
(rest (reverse xs))
reduce takes the provided initial result and list of functions and iteratively applies the functions to the result:
(reduce #(%2 %1) ..init.. ..functions..)

Building a lazy, impure id generator

I'd like to know how to create an infinite, impure sequence of unique values in Clojure.
(def generator ...) ; def, not defn
(take 4 generator) ; => (1 2 3 4)
(take 4 generator) ; => (5 6 7 8). note the generator's impurity.
I think that such a design could be more convenient than e.g. wrapping a single integer value into a reference type and increment it from its consumers, as:
The proposed approach reduces the implementation details to a single point of change: the generator. Otherwise all the consumers would have to care about both the reference type (atom), and the concrete function that provides the next value (inc)
Sequences can take advantage many clojure.core functions. 'Manually' building a list of ids out of an atom would be a bit bulky: (take 4 (repeatedly #(swap! _ inc)))
I couldn't come up with a working implementation. Is it possible at all?
You can wrap a lazy sequence around an impure class (like a java.util.concurrent.atomic.AtomicLong) to create an id sequence:
(def id-counter (java.util.concurrent.atomic.AtomicLong.))
(defn id-gen []
(cons
(.getAndIncrement id-counter)
(lazy-seq
(id-gen))))
This works, but only if you don't save the head of the sequence. If you create a var that captures the head:
(def id-seq (id-gen))
Then call it repeatedly, it will return ids from the beginning of the sequence, because you've held onto the head of the sequence:
(take 3 id-seq)
;; => (0 1 2)
(take 3 id-seq)
;; => (0 1 2)
(take 3 id-seq)
;; => (0 1 2)
If you re-create the sequence though, you'll get fresh values because of the impurity:
(take 3 (id-gen))
;; (3 4 5)
(take 3 (id-gen))
;; (6 7 8)
(take 3 (id-gen))
;; (9 10 11)
I only recommend doing the following for educational purposes (not production code), but you can create your own instance of ISeq which implements the impurity more directly:
(def custom-seq
(reify clojure.lang.ISeq
(first [this] (.getAndIncrement id-counter))
(next [this] (.getAndIncrement id-counter))
(cons [this thing]
(cons thing this))
(more [this] (cons
(.getAndIncrement id-counter)
this))
(count [this] (throw (RuntimeException. "count: not supported")))
(empty [this] (throw (RuntimeException. "empty: not supported")))
(equiv [this obj] (throw (RuntimeException. "equiv: not supported")))
(seq [this] this)))
(take 3 custom-seq)
;; (12 13 14)
(take 3 custom-seq)
;; (15 16 17)
I had a fun time discovering something during answering your question. The first thing that occured to me was that perhaps, for whatever ultimate goal you need these IDs for, the gensym function might be helpful.
Then, I thought "well hey, that seems to increment some impure counter to generate new IDs" and "well hey, what's in the source code for that?" Which led me to this:
(. clojure.lang.RT (nextID))
Which seems to do what you need. Cool! If you want to use it the way you suggest, then I would probably make it a function:
(defn generate-id []
(. clojure.lang.RT (nextID)))
Then you can do:
user> (repeatedly 5 generate-id)
=> (372 373 374 375 376)
I haven't yet tested whether this will produce always unique values "globally"--I'm not sure about terminology, but I'm talking about when you might be using this generate-id function from within different threads, but want to still be sure that it's producing unique values.
this is another solution, maybe:
user=> (defn positive-numbers
([] (positive-numbers 1))
([n] (cons n (lazy-seq (positive-numbers (inc n))))))
#'user/positive-numbers
user=> (take 4 (positive-numbers))
(1 2 3 4)
user=> (take 4 (positive-numbers 5))
(5 6 7 8)
A way that would be more idiomatic, thread-safe, and invites no weirdness over head references would be to use a closure over one of clojures built in mutable references. Here is a quick sample I worked up since I was having the same issue. It simply closes over a ref.
(def id-generator (let [counter (ref 0)]
(fn [] (dosync (let [cur-val #counter]
(do (alter counter + 1)
cur-val))))))
Every time you call (id-generator) you will get the next number in the sequence.
Here's another quick way:
user> (defn make-generator [& [ii init]]
(let [a (atom (or ii 0 ))
f #(swap! a inc)]
#(repeatedly f)))
#'user/make-generator
user> (def g (make-generator))
#'user/g
user> (take 3 (g))
(1 2 3)
user> (take 3 (g))
(4 5 6)
user> (take 3 (g))
(7 8 9)
This is hack but it works and it is extremely simple
; there be dragons !
(defn id-gen [n] (repeatedly n (fn [] (hash #()))))
(id-gen 3) ; (2133991908 877609209 1060288067 442239263 274390974)
Basically clojure creates an 'anonymous' function but since clojure itselfs needs a name for that, it uses uniques impure ids to avoid collitions. If you hash a unique name then you should get a unique number.
Hope it helps
Creating identifiers from an arbitrary collection of seed identifiers:
(defonce ^:private counter (volatile! 0))
(defn- next-int []
(vswap! counter inc))
(defn- char-range
[a b]
(mapv char
(range (int a) (int b))))
(defn- unique-id-gen
"Generates a sequence of unique identifiers seeded with ids sequence"
[ids]
;; Laziness ftw:
(apply concat
(iterate (fn [xs]
(for [x xs
y ids]
(str x y)))
(map str ids))))
(def inf-ids-seq (unique-id-gen (concat (char-range \a \z)
(char-range \A \Z)
(char-range \0 \9)
[\_ \-])))
(defn- new-class
"Returns an unused new classname"
[]
(nth inf-ids-seq (next-int)))
(repeatedly 10 new-class)
Demonstration:
(take 16 (unique-id-gen [\a 8 \c]))
;; => ("a" "8" "c" "aa" "a8" "ac" "8a" "88" "8c" "ca" "c8" "cc" "aaa" "aa8" "aac" "a8a")