How to map a two argument function to a list? - clojure

I have a list of elements with some values in it.
I want to map it to a function and produce a list that contains, values computed by applying this two argument function to consecutive values in the first list.
This list will have one less element.
mapping function should take two arguments at a time.
EDIT
Example
the two argument function I am using is quite complex, so for simplicity lets assume it to be a function that calculated average of two numbers.
if I have a list: [3 8 11 14 19 20 88].
Is it possible for me two write a function that maps my average function which for (average 3 8) will give 5.5
for (average 8 11) will give 9.5
and (average 11 14) will give 12.5
and so on...
on applying average to two consecutive values of the list at a time should give me.
[5.5 9.5 12.5 16.5 19.5 54.0]
as result.
map applies a single argument function to whole list and produces a new list with exactly same number of elements.
what I want is a way to apply my function which takes two arguments to take two consecutive at a time, apply my function to it and add the result to a new list.

You can do it with map:
(map f coll (rest coll))

(fn [f coll] (map #(apply f %1) (partition 2 1 coll))
Go straight to 4clojure now!

Related

Process a changing list using a higher-order function in Clojure

Is there any way to process a changing list using higher-order functions in Clojure and not using explicit recursion? For example, consider the following problem (that I made up to illustrate what I have in mind):
Problem: Given a list of unique integers of unknown order. Write a
that produces an output list as follows:
For any even integer, keep the same relative position in the output list.
For any odd integer, multiply by ten, and put the new number at a new
place: at the back of the original list.
So for example, from original vector [1 2 3 4 5], we get: [2 4 10 30 50]
I know how to solve this using explicit recursion. For example:
(defn process
[v]
(loop
[results []
remaining v]
(if (empty? remaining)
results
(if (even? (first remaining))
(recur (conj results (first remaining)) (rest remaining))
(recur results (conj (vec (rest remaining)) (* 10 (first remaining))))))))
This works fine. Notice that remaining changes as the function does its work. I'm doing the housekeeping here too: shuffling elements from remaining to results. What I would like to do is use a higher-order function that does the housekeeping for me. For example, if remaining did not change as the function does its work, I would use reduce and just kick off the process without worrying about loop or recur.
So my question is: is there any way to process an input (in this example, v) that changes over the course of its operations, using a higher-order function?
(Side note for more context: this question was inspired by Advent of Code 2020, Question 7, first part. There, the natural way to approach it, is to use recursion. I do here (in the find-all-containers function; which is the same way other have approached it, for example, here in the find-outer-bags function, or here in the sub-contains? function.)
This is much easier to do without recursion than with it! Since you only care about the order of evens relative to other evens, and likewise for odds, you can start by splitting the list in two. Then, map the right function over each, and simply concatenate the results.
(defn process [xs]
(let [evens (filter even? xs)
odds (filter odd? xs)]
(concat evens (map #(* 10 %) odds))))
As to the advent of code problem, I recommend working with a better data structure than a list or a vector. A map is a better way to represent what's going on, because you can easily look up the properties of each sub-bag by name. If you have a map from bag color to contents, you can write a simple (recursive) function that asks: "Can color a contain color b?" For leaf nodes the answer is no, for nodes equal to the goal color it's yes, and for branches you recurse on the contents.

Common Lisp function for "Reduce and Return Intermediate Results as Sequence"

In Clojure, there is a higher-order function reductions, which you would use with arguments similar to reduce and will return a sequence containing all intermediate results.
Is there an equivalent in Common Lisp? I was unable to find any reference to it online, including the various books/articles on https://common-lisp.net/tutorials/ but given Lisp's heritage as a family of List Processing languages I imagined a list->list function like reductions will exist across dialects.
There is no standard function for it. You could define one easily:
(defun reductions (function sequence &rest args
&key key from-end (start 0) end initial-value)
(declare (ignore key from-end start end initial-value))
"Return a list of intermediate values from reducing SEQUENCE with FUNCTION."
(let* ((reductions (list))
(result (apply #'reduce
(lambda (&rest arguments)
(let ((result (apply function arguments)))
(push result reductions)
result))
sequence
args)))
(values (or (nreverse reductions)
(list result))
result)))
(reductions #'+ '(1 2 3 4 5 6 7 8 9 10) :initial-value 0)
;=> (1 3 6 10 15 21 28 36 45 55)
Edit: Use APPLY with &REST ARGS instead of calling REDUCE directly. Some implementation of REDUCE might not work if NILs are supplied for keyword arguments.
Edit2: The reducing function can be called with 0 or 2 arguments.
Edit3: When REDUCE is called with a list of only one element, the only element is returned as is. The reducing function is not called at all, which means the list of reductions would be empty. I added an OR to return the final result wrapped in a list in that situation (to match Clojures behaviour). I also changed the code to return the final result as a second return value (might be useful and "why not?").

An explanation of a statement in Clojure?

I need some help about higher-order functions' definition or explanation.
Some guys write a statement like this:
(map inc [9 5 4 8]) ; statement
And after this, an explanation of this statement:
[(inc 9) (inc 5) (inc 4) (inc 8)] ; explanation.
or in (this link) this first message, (reduce + (list 1 2 3 4 5))
"translates to":
(+ (+ (+ (+ 1 2) 3) 4) 5)
Is there a function which gives an explanation of a statement in Clojure?
The trick with understanding higher-order functions is not to over think them - they are actually quite simple. The higher-order function is really just a function which takes another function as one of its arguments and applies that function to each of the arguments in turn and does something with the results generated by applying the function.
You can even think of a higher order function as a mini-program. It takes an argument (a function) which says what to do with the data input (arguments). Each time the function which is passed in is applied to an argument, it generates some new value (which could be nil). The higher order function takes that result and does something with it. In the case of map, it adds it to a new sequence and it is this new sequence that will be returned as the overall result.
Consider a higher order sorting function, lets call it 'sort'. Its first argument is the function which will be used to compare elements to determine which comes first in the sort order and the remaining argument is the list of things to be sorted.
The actual sort function is really just scaffolding or the basic sort engine which ensures the list representing the data is processed until it is sorted. It might implement the basic mechanics for a bubble sort, a quicksort or some other sorting algorithm. Because it is a higher order function, it does not care or even know about how to compare elements to determine the correct order. It relies on the function which is passed in as its first argument to do that. All it wants is for that function to tell it if one value is higher, lower or the same rank as the other.
The function which is passed in to the sort function is the comparison function which determines your sort order. The actual sort function has no knowledge of how to sort the data. It will just keep processing the data until some criteria is met, such as one iteration of the data items where no change in order occurs. It expects the comparison function to take two arguments and return 1, 0 or -1 depending on whether the first argument passed to it is greater, equal or less than the second. If the function returns 1 or 0 it does nothing, but if the value is -1 it swaps A and B and then calls the function again with the new B value and the next value from the list of data. After the first iteration through the input, it will have a new list of items (same items, but different order). It may iterate through this process until no elements are swapped and then returns the final list, which will be sorted according to the sort criteria specified in the comparison function.
The advantage of this higher order function is that you can now sort data according to different sort criteria by simply defining a new comparison function - it just has to take two arguments and return 1, 0 or -1. We don't have to re-write all the low level sorting engine.
Clojure provides a number of basic scaffolding functions which are higher order functions. The most basic of these is map. The map function is very simple - it takes a function and one or more sequences. It iterates through the sequences, taking one element from each sequence and passing them to the function supplied as its first argument. It then puts the result from each call to this argument into a new sequence, which is returned as the final result. This is a little simplified as the map function can take more than one collection. When it does, it takes an element from each collection and expects that the function that was passed as the first argument will accept as many arguments as there are collections - but this is just a generalisation of the same principal, so lets ignore it for now.
As the execution of the map function doesn't change, we don't need to look at it in any detail when trying to understand what is going on. All we need to do is look at the function passed in as the first argument. We look at this function and see what it does based on the arguments passed in and know that the result of the call to map will be a new sequence consisting of all the values returned from applying the supplied function to the input data i.e. collections passed in to map.
If we look at the example you provided
(map inc [9 5 4 8])
we know what map does. It will apply the passed in function (inc) to each of the elements in the supplied collection ([9 5 4 8]). We know that it will return a new collection. To know what it will do, we need to look at the passed in function. The documentation for inc says
clojure.core/inc ([x]) Returns a number one greater than num. Does
not auto-promote longs, will throw on overflow. See also: inc'
I actually think that is a badly worded bit of documentation. Instead of saying "return a number one greater than num, it probably should either say, Return a number one greater than x or it should change the argument name to be ([num]), but yu get the idea - it simply increments its argument by 1.
So, map will apply inc to each item in the collection passed in as the second argument in turn and collect the result in a new sequence. Now we could represent this as [(inc 9) (inc 5) (inc 4) (iinc 8)], which is a vector of clojure forms (expressions) which can be evaluated. (inc 9) => 10, (inc 5) => 6 etc, which will result in [10 6 5 9]. The reason it is expressed as a vector of clojure forms is to emphasise that map returns a lazy sequence i.e. a sequence where the values do not exist until they are realised.
The key point to understand here is that map just goes through the sequences you provide and applies the function you provide to each item from the sequence and collects the results into a new sequence. The real work is done by the function passed in as the first argument to map. To understand what is actually happening, you just need to look at the function map is applying. As this is just a normal function, you can even just run it on its own and provide a test value i.e.
(inc 9)
This can be useful when the function is a bit more complicated than inc.
We cold just stop there as map can pretty much do everything we need. However, there are a few common processing patterns which occur frequently enough that we may want to abstract them out into their own functions, for eample reduce and filter. We could just implement this functionality in terms of map, but it may be complicated by having to track state or be less efficient, so they are abstracted out into their own functions. However, the overall pattern is pretty much the same. Filter is just like map, except the new sequence it generates only contains elements from the input collection which satisfy the predicate function passed in as the first argument. Reduce follows the same basic pattern, the passed in function is applied to elements from the collection to generate a new sequence. The big difference is that it 'reduces' the sequence in some way - either by reducing it to a new value or a new representation (such as hashmap or a set or whatever.
for example,
(reduce + (list 1 2 3 4 5))
follows the same basic pattern of applying the function supplied as the first argument to each of the items in the collection supplied as the second argument. Reduce is slightly different in that the supplied function must take two arguments and in each call following the first one, the first argument passed to the function represents the value returned from the last call. The example above can be written as
(reduce + 0 (list 1 2 3 4 5))
and executes as
(+ 0 1) => 1
(+ 1 2) => 3
(+ 3 3) => 6
(+ 6 4) => 10
(+ 10 5) => 15
so the return value will be 15. However reduce is actually more powerful than is obvious with that little example. The documentation states
clojure.core/reduce ([f coll] [f val coll]) Added in 1.0 f should be
a function of 2 arguments. If val is not supplied, returns the
result of applying f to the first 2 items in coll, then applying f
to that result and the 3rd item, etc. If coll contains no items, f
must accept no arguments as well, and reduce returns the result of
calling f with no arguments. If coll has only 1 item, it is
returned and f is not called. If val is supplied, returns the
result of applying f to val and the first item in coll, then
applying f to that result and the 2nd item, etc. If coll contains no
items, returns val and f is not called.
If you read that carefully, you will see that reduce can be used to accumulate a result which is carried forward with each application of the function. for example, you could use reduce to generate a map containing the sum of the odd and even numbers in a collection e.g.
(defn odd-and-even [m y]
(if (odd? y)
{:odd (+ (:odd m) y)
:even (:even m)}
{:odd (:odd m)
:even (+ (:even m) y)}))
now we can use reduce like this
(reduce odd-and-even {:odd 0 :even 0} [1 2 3 4 5 6 7 8 9 10])
and we get the result
{:odd 25, :even 30}
The execution is like this
(odd-and-even {:odd 0 :even o} 1) -> {:odd 1 :even 0}
(odd-and-even {:odd 1 :even 0} 2) => {:odd 1 :even 2}
(odd-and-even {:odd 1 :even 2} 3) => {:odd 4 :even 2}
(odd-and-even {:odd 4 :even 2) 4) => {:odd 4 :even 6}
....
map applies the function, in this case inc, to the list and returns the result. So its returning a new list which each value incremented by one.
Clojure documentation might be helpful.
There is no function that will print the intermediate values in all cases though there are a couple of tools that may help.
tools.trace helps some print intermediate values such as function calls:
=> (deftrace fubar [x v] (+ x v)) ;; To trace a function call and its return value
=> (fubar 2 3)
TRACE t1107: (fubar 2 3)
TRACE t1107: => 5
5
macroexpand-1 will show you the code generated by macro's such as -> and is essential in learning how to write macros:
=> (macroexpand-1 '(-> 42 inc inc dec inc))
=> (inc (dec (inc (inc 42))))
That second link is talking about reduce not map so the explanation doesn't apply. Map takes a sequence and builds a new sequence by essentially looping through it, calling the function you pass on an element and then adding the result to the list it's building. It iterates down the list until every element has been transformed and included.
reduce which that link is referring to takes an inital value and repeatedly changes that value by calling the function with it and the first value from the sequence, then looping around and calling the function with the updated value and the second item in the list, and then the third and so on until every item in the list has been used to change the value, which it then returns.

clojure partial clarification

I'm reading a book on clojure, and I came by an example that I dont fully understand..
Here is the code in repl:
user=> (repeatedly 10 (rand-int 10))
ClassCastException java.lang.Integer cannot be cast to clojure.lang.IFn clojure.core/repeatedly/fn--4705 (core.clj:4642)
user=> (repeatedly 10 (partial rand-int 10))
(5 0 5 5 2 4 8 8 0 0)
My question is:
why is the partial needed here, and how does that fit into partial definition,
and repeatedly definition & syntax. Partial ...
Takes a function f and fewer than the normal arguments to f, and
returns a fn that takes a variable number of additional args. When
called, the returned function calls f with args + additional args.
So how does this fit in?
Partial is just an easier way of defining an anonymous function that fixes some of the arguments to a function and then passes the rest from the arguments to the created function.
In this case
user> (repeatedly 10 (partial rand-int 10))
(3 1 3 6 1 2 7 1 5 3)
is equivalent to:
user> (repeatedly 10 #(rand-int 10))
(9 5 6 0 0 5 7 6 9 6)
Partial is a misnomer here because partial is being used to fix in advance all the arguments (or rather the only one) to rand-int.
a more intersting use of partial illustrates it's function better:
(partial + 4)
produces the equivalent of:
(fn [& unfixed-args] (apply + (concat [4] unfixed-args)))
(it does not literally produce this)
The idea being to build a function that takes the un-fixed arguments, combines them with the fixed ones, and calls the function you passed to partial with enough arguments to work properly.
user> ((fn [& unfixed-args] (apply + (concat [4] unfixed-args))) 5 6 7 8 9)
39
user> ((partial + 4) 5 6 7 8 9)
39
I only use partial in practice when the number of arguments is variable. Otherwise I have a personal preference towards using the anonymous function reader form #( ... )
partial does not actually check which arities its first argument supports; an arguably more accurate docstring would say that it "takes a function f and some arguments to f". (Clearly if you supply too many arguments, the resulting partially applied function will be broken, though that will only be observable when you try to call it.) So that's why (partial rand-int 10) is ok even though the number of arguments to rand-int supplied is not "fewer than normal".
The reason why either partial or something like #(rand-int 10) is needed here is that repeatedly expects its final argument to be a function which it can repeatedly call, whereas (rand-int 10) would be a number.
Compare this to repeat which returns a sequence with the supplied item repeated the specified number of times (or infinitely many times in the unary case). Here (rand-int 10) would be an appropriate second argument, but of course it would be some particular number, so the result would look like (8 8 8 8 8 ...); repeatedly will make a separate call to (partial rand-int 10) for each item of the sequence returned, so you'll get from it a sequence of (likely different, independent) random numbers.
repeatedly signature we are interested in: (repeatedly number function)
In this case partial will simply wrap rand-int 10 into a function that can be returned and used by the outer function, in this case repeatedly.
Without partial(or #) inner expressions are resolved before the outer ones(there are exceptions, but let's keep it simple for now), so when repeatedly is called without partial, what's gonna be passed to it is a return value of rand-int, that is Int and not a function.

idiomatic use case for func which returns a func

(defn sort-map-by-value
"Given a map return a sorted map, in which the sort is done on the map's values, instead of keys.
Takes a function as an input, which will be used for sorting"
[cf kf]
(fn [m]
(->> m
map-invert
(into (sorted-map-by #(cf (kf %1) (kf %2))))
map-invert)))
(defn date-time-comparator
"Predicate function for comparing two date-time's"
[time1 time2]
(before? time1 time2))
(defn get-time-value
"Function for extracting the date-time from the value of the given map."
[v]
(-> v first :time))
(def sort-map-by-date (sort-map-by-value date-time-comparator get-time-value))
(sort-map-by-date {"3-19-2013" [{:time (date-time 2013 3 19 12 14 45)}]
"3-9-2013" [{:time (date-time 2013 3 9 16 46 49)}]
"2-25-2013" [{:time (date-time 2013 2 25 2 38 15)}]
"3-14-2013" [{:time (date-time 2013 3 14 7 19 23)}]
"2-8-2013" [{:time (date-time 2013 2 8 12 44 47)}]
})
I am trying to understand what is the idiomatic pattern for using higher-order-functions. Specifically for the functions that return functions. The first function sort-map-by-value, takes 2 fns as parameter and returns a function which takes a map as a parameter.
The above function could as well take all three, the 2 funcs and the map as a parameter. So there is no need to create a function which would return another func in this case. What would be a case where it would be needed. Or in other words what is the idiomatic pattern for introducing a function which returns a function ?
The example shown could have been achieved using partial function application in case the function took the map also as parameter.
Basically, function returning a function is a specific case of partial application i.e you do not pass all the params to a function and in return you get a function which will take remaining params and execute the original function. I personally like to use partial application using partial or using anonymous functions to create partial functions (ex: #(map inc %)).
Why we need them? For one things, they act as glue when you program using function composition. For ex:
You want to write a function that increment each number in a vector and then reverse it.
You can write it without function composition:
(defn foo [v]
(reverse (map inc v)))
Using function composition:
(def foo (comp reverse (partial map inc)))
This may not be the best example but I hope you get the idea.
Another example could be wrapper functions. They take input as a function and return another function (which takes same number of params as the original one) and do something before or after executing the original function (ex: Ring middleware)
I agree with the previous response about partial. And then there's comp which takes multiple fn's as input and returns the composition of them as output.
Here's an example that might help, although the output isn't quite a fn. I wanted to have background threads repeatedly executing some tasks in regular intervals. Each background thread executes one specific task, but the task differs from one thread to the next. So it made sense to have a HOF that takes a fn representing the task to repeat and returns a Thread, where the Thread is created that performs the input fn incessantly. The input fn is made to execute non-stop inside the Thread by being wrapped within a repeatedly form.
partial is the most likely way in which a HOF where the input and output are both a single fn each. The example I gave is what happens when the input fn is needed only for its side effects, so there's no point for the HOF's output to be a fn, if there the HOF has an output at all.