Basically, I need to do something like map, but instead of applying a function to all elements in a collection, I need to apply the same (set of) value(s) to a collection of functions (does this operation have a name?). This might seem like a simple question, but I haven't found an idiomatic way to do it in Clojure. For the special case where I need to apply only one value to each function, for example, I have used
(for [f funs] (f value))
where value is, of course, the value I need each function to take as an argument, and funs is the collection of functions which need to be called with value as the argument.
My question is, then, is there a function in Clojure that does this, but is also generalised for arbitrary numbers of arguments? Or is the above indeed idiomatic Clojure?
You're looking for juxt
juxt
Takes a set of functions and returns a fn that is the juxtaposition
of those fns. The returned fn takes a variable number of args, and
returns a vector containing the result of applying each fn to the
args (left-to-right).
((juxt a b c) x) => [(a x) (b x) (c x)]
From a section of CLOJURE for the BRAVE and TRUE
Another fun thing you can do with map is pass it a collection of
functions. You could use this if you wanted to perform a set of
calculations on different collections of numbers, like so:
(def sum #(reduce + %))
(def avg #(/ (sum %) (count %)))
(defn stats
[numbers]
(map #(% numbers) [sum count avg]))
(stats [3 4 10])
; => (17 3 17/3)
(stats [80 1 44 13 6])
; => (144 5 144/5)
Related
first I am not looking for answer to this question I simplying looking for clarification. This is for a 4clojure question and the wording is a bit ambigious and doesn't seem to cover ever example. The question is: http://www.4clojure.com/problem/166
Text:
For any orderable data type it's possible to derive all of the basic comparison operations (<, ≤, =, ≠, ≥, and >) from a single operation (any operator but = or ≠ will work). Write a function that takes three arguments, a less than operator for the data and two items to compare. The function should return a keyword describing the relationship between the two items. The keywords for the relationship between x and y are as follows:
x = y → :eq
x > y → :gt
x < y → :lt
I believe that compare can be used to implement all comparision operators. Am I correct?
I believe the question wants me to change the return type of the less than operator and the greater than operator so that they return :lt, :gt, and :eq
4clojure does not allow defmacro.
My question is am I correct in my assumption that I am supposed to overwrite the return type of < and >?
If I am correct is there a way to do this with out a macro?
Please do not post an answer for the 4clojure question, just a general clarification of the problem would help. The text also mentions writing a function that takes in < yet one of the examples uses >. So a bit confused on what is being asked for here. I am supposed to use the output of the function being passed into my function correct or am I suppose to write a function that overides the < and > operators inside the functions being passed in?
The question is asking you to define a function like
(defn compare [lt x y] ...)
where lt is a function of two parameters which returns whether the first parameter is less than the first e.g.
(defn compare [lt x y]
(if (lt x y)
...))
In fact, there is a special function for that in clojure core: comparator. It generates the comparator from any function taking two args and returning truthy or falsey val. That comparator is itself a function, returning -1 when function is true for arg1 and arg2, 1 when function is true for arg2 and arg1 and 0 otherwise:
user> ((comparator <) 1 2)
-1
user> ((comparator <) 2 1)
1
user> ((comparator <) 1 1)
0
user> ((comparator (fn [a b] (< (count a) (count b)))) [1 2 3] [4])
1
user> ((comparator (fn [a b] (< (count a) (count b)))) [] [4])
-1
user> ((comparator (fn [a b] (< (count a) (count b)))) [10] [4])
0
so, applied to the task from 4clojure it is enough to create the comparator, compare vals and get needed indicator for -1, 0 or 1.
I'm trying to do a really basic problem in clojure and having some trouble wrapping my head around how vectors/lists work.
First off when I am defining the arguments of a function that has a vector as an argument, how do you represent that as an argument.
Would you just have it as a single variable say
(defn example [avector] (This is where the function goes) )
Or do you have to list each element of a vector or list beforehand?
(defn example [vectorpart1 vectorpart2 vectorpart3 vectorpart4 ] (This is where the function goes) )
Also, in terms of vectors and lists, does anyone know of commands that allow you to figure out the length of a vector or get the first/last/or nth element?
To remove the element at index n from vector v:
(defn remove-indexed [v n]
(into (subvec v 0 n) (subvec v (inc n))))
For example,
(remove-indexed (vec (range 10)) 5)
;[0 1 2 3 4 6 7 8 9]
Lots can go wrong:
v might not be a vector.
n might not be a whole number.
n might be out of range for v (we require (contains? v n).
Clojure detects all these errors at run time. A statically typed language would detect 1 and 2 but not 3 at compile time.
Your first example defines a function that takes a single argument, regardless of type. If you pass a vector then that argument will be set to a vector.
(example [1 2 3 4]) ;; (= avector [1 2 3 4])
Your second example defines a function which takes four arguments. You need to pass four separate values for calls to this function to be valid.
(example [1] [2] [3] [4])
;; (= vectorpart1 [1])
;; (= vectorpart2 [2])
;; (= vectorpart3 [3])
;; (= vectorpart4 [4])
It sounds like you might be thinking about the destructuring syntax, which allows you to destructure values directly from an argument vector.
(defn example [[a b c d]]
())
The literal vector syntax in the argument definition describes a mapping between the items in the first argument and symbols available in the function scope.
(example [1 2 3 4])
;; (= a 1)
;; (= b 2)
;; (= c 3)
;; (= d 4)
The other function that also sits in this space is apply. Apply takes a list or vector of arguments and calls a function with them in-place.
(defn example [a b c]
(assert (= a 1))
(assert (= b 2))
(assert (= c 3)))
If we call this function with one vector, you'll get an arity exception.
(example [1 2 3])
;; ArityException Wrong number of args (1) passed ...
Instead we can use apply to pass the vector as arguments.
(apply example [1 2 3])
;; no errors!
You'll find all the methods you need to work with vectors in the Clojure docs.
If you want to remove a specific element, simply take the elements before it and the elements after it, then join them together.
(def v [1 2 3])
(concat (subvec v 0 1) (subvec v 2))
The short answer is that your first example is correct. You don't want to have to name every piece of your vector because you will commonly work with vectors of indeterminate length. If you want to do something with that vector where you need its parts to be assigned, you can do so by destructuring.
The slightly longer answer is that the list of parameters sent into any clojure defn already is a vector. Notice that the parameter list uses [] to wrap its list of args. This is because in Clojure code and data are the same thing. From this article...
Lisps are homoiconic, meaning code written in the language is encoded as data structures that the language has tools to manipulate.
This might be more than you're looking for but it's an important related concept.
Here'a a quick example to get you going... Pass a vector (of strings in this case) to a functions and it returns the vector. If you map over it however, it passes the contents of the vector to the function in succession.
user=> (def params ["bar" "baz"])
#'user/params
user=> (defn foo [params] (println params))
#'user/foo
user=> (foo params)
[bar baz]
nil
user=> (map foo params)
bar
baz
(nil nil)
Additionally, look at the Clojure cheatsheet to find more about things you can do with vectors (and everything else in Clojure).
I'm using the http-kit library to make some webcalls and it returns a promise for each.
When I try to deref any of the promises in the vector I get the following error
ArityException Wrong number of args (1) passed to: core/eval5473/fn--5474 clojure.lang.AFn.throwArity (AFn.ja
va:429)
Simplest way to reproduce in a repl without http-kit is as follows
Create collection
(def x [ [1 (promise)] [2 (promise)] [3 (promise)]])
Simple Test
(map first x)
;user=> (1 2 3)
My Test
(map #(vector % #%2) x)
;user=> ArityException Wrong number of args (1) passed to: user/eval109/fn--110 clojure.lang.AFn.throwArity (AFn.java
:429)
Update
I should probably delete this question. The problem had nothing to do with promises as Valentin noted below.
I was typing %2 and thinking second argument. When what i needed was #(second %). i.e second entry in first and only argument.
The function that is the second argument of map must accept only 1 argument in this case (which is meant to be an element of the seq that is being walked through).
You seem to be mistaking passing 2 arguments to a function and passing 1 argument that is a vector of 2 elements.
What you want to write is
(map (fn [[a b]] (vector a #b)) x)
...whereas what you're currently writing is equivalent to:
(map (fn [a b] (vector a #b)) x)
So this is not a problem about promises in fact.
I am doing the closure tutorial at http://clojurescriptkoans.com and I am stuck here: http://clojurescriptkoans.com/#functions/9
It looks like this
Higher-order functions take function arguments
(= 25 ( _ (fn [n] (* n n))))
I am supposed to fill in something at the underscore to make the expression true. I have no clue what to do.
The syntax simply consists of binding the function, and then calling it.
Since this is an exercise, I will show a similar situation rather than showing the exercise's solution:
user> ((fn [f] (f "abc")) (fn [s] (str s s s)))
"abcabcabc"
here I bind the argument of the first function to f, and call f with the argument "abc".
or you can use the short-hand notation:
#(%1 5)
Higher order functions takes functions as arguments.
Defining two functions
user=> (defn multiply [n] (* n n))
#'user/multiply
user=> (defn add [n] (+ n n))
#'user/add
Defining higher order function
user=> (defn highorderfn [fn number] (fn number))
#'user/highorderfn
Calling the higher order function
user=> (highorderfn multiply 5)
25
user=> (highorderfn add 5)
10
Examples of Clojure arity-overloading on functions like the following (taken from the cookbook):
(defn argcount
([] 0) ; Zero arguments
([x] 1) ; One argument
([ x & args] (inc (count args)))) ; List of arguments
... use a form that doesn't seem to allow the functions of lower arity to simply call the functions of higher arity with some default values (that's a common idiom in Java).
Is some other special form used for that ?
There's usually a good way to express the higher arity arguments in a way that doesn't need to refer to other arities using higher order functions and map / reduce. In this case it's pretty simple:
(defn argcount
([] 0)
([x] 1)
([x & args]
(reduce + 1 (map (constantly 1) args))))
Notice the general form of the expression is:
(reduce reducing-function arity-1-value (map mapping-function rest-of-args))
You can't do everything this way, but this works for a surprisingly large proportion of multi-argument functions. It also gains the advnatages of laziness using map, so you can do crazy things like pass ten million arguments to a function with little fear:
(apply argcount (take 10000000 (range)))
=> 10000000
Try that in most other languages and your stack will be toast :-)
mikera's answer is awesome; I'd just add an additional method.
When the a default value is needed for an overloaded function, a local can be used.
In the example division below, the local requires numbers and precision. The defined function overloads the precision with a default value.
(def overloaded-division
(let [divide-with-precision
(fn [divisor dividend precision]
(with-precision precision (/ (bigdec divisor) (bigdec dividend))))]
(fn
;lower-arity calls higher with a default precision.
([divisor dividend] (divide-with-precision divisor dividend 10))
;if precision is supplied it is used.
([divisor dividend precision] (divide-with-precision divisor dividend precision)))
)
)
When called at lower-arity, the default it applied:
user=> (overloaded-division 3 7)
0.4285714286M
user=> (overloaded-division 3 7 40)
0.4285714285714285714285714285714285714286M