What is the equivalent of Wolfram Language's Fold in ClojureScript? - clojure

In Wolfram Language aka Mathematica ( a Lisp )
Fold[g, 0, {a,b,c}]
evaluates to
g[g[g[0,a],b],c]
so when
f[x_,y_]:=10 x + y
then
Fold[f, 0, {1,2,3,4}]
evaluates to ( creates a number from the digits )
1234
What is the equivalent of Wolfram Language's Fold in ClojureScript ?

The math function fold comes in a few flavors fold left, and fold right which differ in the direction the function is applied. Clojure's reduce is fold left
Also in clojure compared to other languages with fold the reducing function will be called with several different numbers of arguments.
first lets define a function that tells us it's args
user> (defn ++ [& args]
(println "++ called with" args)
(apply + args))
#'user/++
If your list is empty the reducing function is called with no arguments to produce the "identity" value. for addition identity is zero, for / it's 1, etc.
user> (reduce ++ [])
++ called with nil
0
for a single item list it's not called at all
user> (reduce ++ [1])
1
and for the rest of the cases it's called with two arguments and applies the function as if it where a left associated operator (in inflix languages) or just a plain old function call in lisp.
user> (reduce ++ [1 2])
++ called with (1 2)
3
user> (reduce ++ [1 2 3])
++ called with (1 2)
++ called with (3 3)
6

Here you go:
(reduce
(fn [r x] (+ (* r 10) x))
0 [1 2 3 4])

Related

Evaluate Vector of Forms with Parameters

I've been working to figure out a was to evaluate collections of forms with arguments.
An example function:
(defn x
[a b c]
(+ a b c))
I would like to evaluate collections of the function x, where only some parameters are defined and others are passed in to end up with a list of the products of the evaluations of the x functions in the collection:
(defn y
[z]
(map #(eval %) [(x z 1 1) (x z 2 2) (x z 8 64)]))
The question is: how do I introduce z as a parameter to each of the functions in the collection when I map eval to each? Is this possible?
I am trying to avoid typing them all out because I have many inputs (hundreds) that I want to pass to x where I only have a small set of the second and third parameters (five or so) that I care about.
Is there a better way to accomplish this?
Thanks!
First, let's use some more explanatory names, simplify the definition of x, and not use eval:
(defn sum [& xs]
(apply + xs)) ;; could be inlined instead of a function
(defn sum-with [z]
(map (partial apply sum)
[[z 1 1]
[z 2 2]
[z 8 64]]))
(sum-with 3)
=> (5 7 75)
But I assume your real world problem is something more complex than summing numbers, so I'll assume your x function is doing something else and requires some positional arguments i.e. the order of arguments matters:
(defn transmogrify [this n1 n2 that]
(+ n1 n2 (* this that)))
(defn evaluate-sums [a b]
(map (partial apply transmogrify)
[[a 1 1 b]
[a 2 2 b]
[a 8 64 b]]))
(evaluate-sums 3 9)
=> (29 31 99)
So if I understand correctly, you can accomplish your goal just by applying sequences of arguments to your function. Or to be more explicit with args/not use apply, just use a more specific anonymous function with map:
(defn evaluate-sums [z]
(map (fn [[this n1 n2 that]]
(transmogrify this n1 n2 that))
[[z 1 1 99]
[z 2 2 360]
[z 8 64 -1]]))
I am trying to avoid typing them all out because I have many inputs (hundreds) that I want to pass to x where I only have a small set of the second and third parameters (five or so) that I care about.
If your "fixed" arguments are always the same arity, then you can use variadic arity for the rest of the arguments:
(defn sum [a b & cs]
(apply + a b cs))
(defn evaluate-sums [zs]
(map (fn [[a b & cs]]
(apply sum a b cs))
[[1 1 zs]
[2 2 zs]
[8 64 zs]]))
Where zs is a collection/sequence of your extra arguments.

Calling a macro on a macro

I'm trying to write a Clojure macro that creates a prefix notation list for evaluation from a simple infix notation list, say (2 * 3 + 4 * 2) to an evaluated(+ (* 2 3) (*4 2)) (resulting in 14 being returned).
I have written the following code:
(defmacro infix [op inlist]
(let [[i1 i2 & i3] inlist
last-group? (nil? (second i3))]
(if last-group?
`(if (= ~op ~i2)
(~i2 ~i1 ~(first i3)) ; return unevaluated prefix list
(~i1 ~i2 ~(first i3))) ; return unevaluated infix list
`(if (= ~op ~i2)
; recur with prefix list in i1 position
(infix ~op ~(conj (rest i3) (list i2 i1 (first i3)) ))
; return as list: i1 and i2, recur i3 (probably wrong)
(~i1 ~i2 (infix ~op ~i3))
))))
With the intention of enforcing operator precedence by calling the macro recursively with different op (operator function) parameters:
(infix + (infix * (2 * 3 + 4 * 2)))
Above, I'm just using it with two * and +, but ultimately I'd want to call the macro for all (or at least for the sake of this exercise, / * + -) operators.
When I execute the above nested macro call, I get the following error:
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'cbat.ch7.ex2/infix, compiling:(/tmp/form-init4661580047453041691.clj:1:1)
Calling the macro for a single operator and a list of the same operator (i.e. (infix * (2 * 3 * 4))) works as expected. If I call the macro with a single (i1 i2 i3) list, if op differs from i2, it tries to (understandably) return the unevaluated infix list with the error:
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn cbat.ch7.ex2/eval3003 (form-init4661580047453041691.clj:1)
I was hoping calling the macro recursively would mean that I could process the unevaluated infix list before the entire line was evaluated, but this doesn't seem to work.
I'm pretty sure the else branch of the latter, inner if (i.e. (~i1 ~i2 (infix ~op ~i3))) is incorrect and I may just need the inner infix call, but I'm more concerned with getting the nested macro calls for the different operators working prior to evaluation.
I know that this isn't the usual way of converting infix to prefix notation, and have since found out about Dijkstra's shunting-yard algorithm, but please could someone kindly enlighten me as to:
whether such nested macro calls are possible?
whether my logic is reasonable, and not too far from a solution? If so...
... what changes I need to make to get things running?
I'm really focused on learning Clojure, so any thorough explanation (where possible) will be most welcome.
You can nest macro calls as this code demonstrates:
(defmacro mac [tag & forms]
`(do
(println "mac - enter" ~tag)
~#forms
(println "mac - exit " ~tag)))
(mac :a
(doseq [i (range 3)]
(mac :b (println i))))
mac - enter :a
mac - enter :b
0
mac - exit :b
mac - enter :b
1
mac - exit :b
mac - enter :b
2
mac - exit :b
mac - exit :a
You can also make recursive macro calls as this shows:
(defmacro macr [n]
(if (zero? n)
1
`(* ~n (macr ~(dec n)))))
(macr 5) => 120
Without delving too deep into your particular implementation, I would suggest 2 points:
At least to start, keep your forms as simple as possible. This means only forms like (2 + 3). And especially don't force the macro to figure out operator precedence in the early versions (or ever!).
Macros are almost never necessary, and it is unfortunate IMHO that they are somewhat "over-hyped" when learning Clojure & other lisps. I would suggest you don't even think about them for the first year or two, as they are more brittle than functions and less powerful in important ways (you can't pass a macro into a function, for example).
Update
Whenever you want to write something complicated (a macro definitely qualifies!), start small and
build it up one step at a time. Using the lein-test-refresh plugin and the Tupelo library definitely help
here.
First, make the simplest possible macro and observe its behavior:
(ns tst.clj.core
(:use clj.core clojure.test tupelo.test)
(:require [tupelo.core :as t] ))
(t/refer-tupelo)
(defn infix-fn [[a op b]]
(spyx a)
(spyx op)
(spyx b)
)
(defmacro infix [form]
(infix-fn form))
(infix (2 + 3))
a => 2
op => +
b => 3
For many macros, it is helpfully to send the marcro args to a helper function like infix-fn. The
spyx helps us by printing the symbol and its value. At this point, we can simply re-order the
args into prefix notation and away we go:
(defn infix-fn [[a op b]] (list op a b))
(defmacro infix [form] (infix-fn form))
(deftest master
(is= 5 (infix (2 + 3)))
(is= 6 (infix (2 * 3))))
What if we have a recursive tree structure? Check if we need to recurse in infix-fn:
(declare infix-fn)
(defn simplify [arg]
(if (list? arg)
(infix-fn arg)
arg))
(defn infix-fn [[a op b]]
(list op (simplify a) (simplify b)))
(is= 7 (infix ((2 * 2) + 3)))
(is= 9 (infix ((1 + 2) * 3)))
(is= 35 (infix ((2 + 3) * (3 + 4))))
(is= 26 (infix ((2 * 3) + (4 * 5))))
I would not want to add in the complication of operator precedence. If absolutely necessary, I
would not code it up myself but would use the excellent Instaparse library for that purpose.
expansion of your call would give you a clue:
(if (= + *)
(* infix (2 * 3 + 4 * 2))
(infix * (2 * 3 + 4 * 2)))
You've got the wrong presumption that the argument of macro would be expanded before the macro itself, i guess. But in fact in this one: (~i2 ~i1 ~(first i3)) i1 is still infix symbol. As far as i can see, the solution is to add some new condition branch, treating infix form some special way.

mapcat breaking the lazyness

I have a function that produces lazy-sequences called a-function.
If I run the code:
(map a-function a-sequence-of-values)
it returns a lazy sequence as expected.
But when I run the code:
(mapcat a-function a-sequence-of-values)
it breaks the lazyness of my function. In fact it turns that code into
(apply concat (map a-function a-sequence-of-values))
So it needs to realize all the values from the map before concatenating those values.
What I need is a function that concatenates the result of a map function on demand without realizing all the map beforehand.
I can hack a function for this:
(defn my-mapcat
[f coll]
(lazy-seq
(if (not-empty coll)
(concat
(f (first coll))
(my-mapcat f (rest coll))))))
But I can't believe that clojure doesn't have something already done. Do you know if clojure has such feature? Only a few people and I have the same problem?
I also found a blog that deals with the same issue: http://clojurian.blogspot.com.br/2012/11/beware-of-mapcat.html
Lazy-sequence production and consumption is different than lazy evaluation.
Clojure functions do strict/eager evaluation of their arguments. Evaluation of an argument that is or that yields a lazy sequence does not force realization of the yielded lazy sequence in and of itself. However, any side effects caused by evaluation of the argument will occur.
The ordinary use case for mapcat is to concatenate sequences yielded without side effects. Therefore, it hardly matters that some of the arguments are eagerly evaluated because no side effects are expected.
Your function my-mapcat imposes additional laziness on the evaluation of its arguments by wrapping them in thunks (other lazy-seqs). This can be useful when significant side effects - IO, significant memory consumption, state updates - are expected. However, the warning bells should probably be going off in your head if your function is doing side effects and producing a sequence to be concatenated that your code probably needs refactoring.
Here is similar from algo.monads
(defn- flatten*
"Like #(apply concat %), but fully lazy: it evaluates each sublist
only when it is needed."
[ss]
(lazy-seq
(when-let [s (seq ss)]
(concat (first s) (flatten* (rest s))))))
Another way to write my-mapcat:
(defn my-mapcat [f coll] (for [x coll, fx (f x)] fx))
Applying a function to a lazy sequence will force realization of a portion of that lazy sequence necessary to satisfy the arguments of the function. If that function itself produces lazy sequences as a result, those are not realized as a matter of course.
Consider this function to count the realized portion of a sequence
(defn count-realized [s]
(loop [s s, n 0]
(if (instance? clojure.lang.IPending s)
(if (and (realized? s) (seq s))
(recur (rest s) (inc n))
n)
(if (seq s)
(recur (rest s) (inc n))
n))))
Now let's see what's being realized
(let [seq-of-seqs (map range (list 1 2 3 4 5 6))
concat-seq (apply concat seq-of-seqs)]
(println "seq-of-seqs: " (count-realized seq-of-seqs))
(println "concat-seq: " (count-realized concat-seq))
(println "seqs-in-seq: " (mapv count-realized seq-of-seqs)))
;=> seq-of-seqs: 4
; concat-seq: 0
; seqs-in-seq: [0 0 0 0 0 0]
So, 4 elements of the seq-of-seqs got realized, but none of its component sequences were realized nor was there any realization in the concatenated sequence.
Why 4? Because the applicable arity overloaded version of concat takes 4 arguments [x y & xs] (count the &).
Compare to
(let [seq-of-seqs (map range (list 1 2 3 4 5 6))
foo-seq (apply (fn foo [& more] more) seq-of-seqs)]
(println "seq-of-seqs: " (count-realized seq-of-seqs))
(println "seqs-in-seq: " (mapv count-realized seq-of-seqs)))
;=> seq-of-seqs: 2
; seqs-in-seq: [0 0 0 0 0 0]
(let [seq-of-seqs (map range (list 1 2 3 4 5 6))
foo-seq (apply (fn foo [a b c & more] more) seq-of-seqs)]
(println "seq-of-seqs: " (count-realized seq-of-seqs))
(println "seqs-in-seq: " (mapv count-realized seq-of-seqs)))
;=> seq-of-seqs: 5
; seqs-in-seq: [0 0 0 0 0 0]
Clojure has two solutions to making the evaluation of arguments lazy.
One is macros. Unlike functions, macros do not evaluate their arguments.
Here's a function with a side effect
(defn f [n] (println "foo!") (repeat n n))
Side effects are produced even though the sequence is not realized
user=> (def x (concat (f 1) (f 2)))
foo!
foo!
#'user/x
user=> (count-realized x)
0
Clojure has a lazy-cat macro to prevent this
user=> (def y (lazy-cat (f 1) (f 2)))
#'user/y
user=> (count-realized y)
0
user=> (dorun y)
foo!
foo!
nil
user=> (count-realized y)
3
user=> y
(1 2 2)
Unfortunately, you cannot apply a macro.
The other solution to delay evaluation is wrap in thunks, which is exactly what you've done.
Your premise is wrong. Concat is lazy, apply is lazy if its first argument is, and mapcat is lazy.
user> (class (mapcat (fn [x y] (println x y) (list x y)) (range) (range)))
0 0
1 1
2 2
3 3
clojure.lang.LazySeq
note that some of the initial values are evaluated (more on this below), but clearly the whole thing is still lazy (or the call would never have returned, (range) returns an endless sequence, and will not return when used eagerly).
The blog you link to is about the danger of recursively using mapcat on a lazy tree, because it is eager on the first few elements (which can add up in a recursive application).

Pass multiple parameters function from other function with Clojure and readability issues

I'm trying to learn functional programming with SICP. I want to use Clojure.
Clojure is a dialect of Lisp but I'm very unfamiliar with Lisp. This code snippet unclean and unreadable. How to write more efficient code with Lisp dialects ?
And how to pass multiple parameters function from other function ?
(defn greater [x y z]
(if (and (>= x y) (>= x z))
(if (>= y z)
[x,y]
[x,z])
(if (and (>= y x) (>= y z))
(if (>= x z)
[y,x]
[y,z])
(if (and (>= z x) (>= z y))
(if (>= y x)
[z,y]
[z,x])))))
(defn sum-of-squares [x y]
(+ (* x x) (* y y)))
(defn -main
[& args]
(def greats (greater 2 3 4))
(def sum (sum-of-squares greats)))
You are asking two questions, and I will try to answer them in reverse order.
Applying Collections as Arguments
To use a collection as an function argument, where each item is a positional argument to the function, you would use the apply function.
(apply sum-of-squares greats) ;; => 25
Readability
As for the more general question of readability:
You can gain readability by generalizing the problem. From your code sample, it looks like the problem consists of performing the sum, of the squares, on the two largest numbers in a collection. So, it would be visually cleaner to sort the collection in descending order and take the first two items.
(defn greater [& numbers]
(take 2 (sort > numbers)))
(defn sum-of-squares [x y]
(+ (* x x) (* y y)))
You can then use apply to pass them to your sum-of-squares function.
(apply sum-of-squares (greater 2 3 4)) ;; => 25
Keep in Mind: The sort function is not lazy. So, it will both realize and sort the entire collection you give it. This could have performance implications in some scenarios. But, in this case, it is not an issue.
One Step Further
You can further generalize your sum-of-squares function to handle multiple arguments by switching the two arguments, x and y, to a collection.
(defn sum-of-squares [& xs]
(reduce + (map #(* % %) xs)))
The above function creates an anonymous function, using the #() short hand syntax, to square a number. That function is then lazily mapped, using map, over every item in the xs collection. So, [1 2 3] would become (1 4 9). The reduce function takes each item and applies the + function to it and the current total, thus producing the sum of the collection. (Because + takes multiple parameters, in this case you could also use apply.)
If put it all together using one of the threading macros, ->>, it starts looking very approachable. (Although, an argument could be made that, in this case, I have traded some composability for more readability.)
(defn super-sum-of-squares [n numbers]
(->> (sort > numbers)
(take n)
(map #(* % %))
(reduce +)))
(super-sum-of-squares 2 [2 3 4]) ;;=> 25
(defn greater [& args] (take 2 (sort > args)))
(defn -main
[& args]
(let [greats (greater 2 3 4)
sum (apply sum-of-squares greats)]
sum))
A key to good clojure style is to use the built in sequence operations. An alternate approach would have been a single cond form instead of the deeply nested if statements.
def should not be used inside function bodies.
A function should return a usable result (the value returned by -main will be printed if you run the project).
apply uses a list as the args for the function provided.
To write readable code, use the functions provided by the language as much as possible:
e.g. greater can be defined as
(defn greater [& args]
(butlast (sort > args)))
To make sum-of-squares work on the return value from greater, use argument destructuring
(defn sum-of-squares [[x y]]
(+ (* x x) (* y y)))
which requires the number of elements in the argument sequence to be known,
or define sum-of-squares to take a single sequence as argument
(defn sum-of-squares [args]
(reduce + (map (fn [x] (* x x)) args)))

Cleaning up Clojure function

Coming from imperative programming languages, I am trying to wrap my head around Clojure in hopes of using it for its multi-threading capability.
One of the problems from 4Clojure is to write a function that generates a list of Fibonacci numbers of length N, for N > 1. I wrote a function, but given my limited background, I would like some input on whether or not this is the best Clojure way of doing things. The code is as follows:
(fn fib [x] (cond
(= x 2) '(1 1)
:else (reverse (conj (reverse (fib (dec x))) (+ (last (fib (dec x))) (-> (fib (dec x)) reverse rest first))))
))
The most idiomatic "functional" way would probably be to create an infinite lazy sequence of fibonacci numbers and then extract the first n values, i.e.:
(take n some-infinite-fibonacci-sequence)
The following link has some very interesting ways of generating fibonnaci sequences along those lines:
http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci
Finally here is another fun implementation to consider:
(defn fib [n]
(let [next-fib-pair (fn [[a b]] [b (+ a b)])
fib-pairs (iterate next-fib-pair [1 1])
all-fibs (map first fib-pairs)]
(take n all-fibs)))
(fib 6)
=> (1 1 2 3 5 8)
It's not as concise as it could be, but demonstrates quite nicely the use of Clojure's destructuring, lazy sequences and higher order functions to solve the problem.
Here is a version of Fibonacci that I like very much (I took the implementation from the clojure wikibook: http://en.wikibooks.org/wiki/Clojure_Programming)
(def fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
It works like this: Imagine you already have the infinite sequence of Fibonacci numbers. If you take the tail of the sequence and add it element-wise to the original sequence you get the (tail of the tail of the) Fibonacci sequence
0 1 1 2 3 5 8 ...
1 1 2 3 5 8 ...
-----------------
1 2 3 5 8 13 ...
thus you can use this to calculate the sequence. You need two initial elements [0 1] (or [1 1] depending on where you start the sequence) and then you just map over the two sequences adding the elements. Note that you need lazy sequences here.
I think this is the most elegant and (at least for me) mind stretching implementation.
Edit: The fib function is
(defn fib [n] (nth fib-seq n))
Here's one way of doing it that gives you a bit of exposure to lazy sequences, although it's certainly not really an optimal way of computing the Fibonacci sequence.
Given the definition of the Fibonacci sequence, we can see that it's built up by repeatedly applying the same rule to the base case of '(1 1). The Clojure function iterate sounds like it would be good for this:
user> (doc iterate)
-------------------------
clojure.core/iterate
([f x])
Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects
So for our function we'd want something that takes the values we've computed so far, sums the two most recent, and returns a list of the new value and all the old values.
(fn [[x y & _ :as all]] (cons (+ x y) all))
The argument list here just means that x and y will be bound to the first two values from the list passed as the function's argument, a list containing all arguments after the first two will be bound to _, and the original list passed as an argument to the function can be referred to via all.
Now, iterate will return an infinite sequence of intermediate values, so for our case we'll want to wrap it in something that'll just return the value we're interested in; lazy evaluation will stop the entire infinite sequence being evaluated.
(defn fib [n]
(nth (iterate (fn [[x y & _ :as all]] (cons (+ x y) all)) '(1 1)) (- n 2)))
Note also that this returns the result in the opposite order to your implementation; it's a simple matter to fix this with reverse of course.
Edit: or indeed, as amalloy says, by using vectors:
(defn fib [n]
(nth (iterate (fn [all]
(conj all (->> all (take-last 2) (apply +)))) [1 1])
(- n 2)))
See Christophe Grand's Fibonacci solution in Programming Clojure by Stu Halloway. It is the most elegant solution I have seen.
(defn fibo [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))
(take 10 (fibo))
Also see
How can I generate the Fibonacci sequence using Clojure?