I want to be able to do the following pseudocode:
Pass in symbol a.
Pass in symbol b.
Pass in an expression using a and b
As I change the value of a and b, print the output of c at each moment.
Ideally, I would like the signature to look like:
(runner a b (+ a b))
but I'm not sure that I'm approaching this correctly... I've tried changing the function to
(runner 'a 'b (+ 'a 'b))
and this more complicated example:
(runner 'a 'b (+ (* 'a 'b) 'a))
but this does a + on 'a and 'b before stepping into runner.
Here's my first stab at some clojure:
(defn runner [a b c] (
(for [i (range 10)
j (range 10)] (println i j (c i j))
What concept of clojure am I missing?
Function arguments are always evaluated before the function is called. If you want to defer evaluation or represent some computation or code as an object, you have a few options:
Use a function (see my code below)
Use a macro and splice some code into some other code that the macro generates
Pass code as a quoted list, and eval it.
Using a function is what you want to do 99% of the time. 1% of the time, you'll want macros. You should never need eval unless you're generating code at runtime or doing very screwy things.
user> (defn runner [f]
(doseq [a (range 3)
b (range 3)]
(println a b (f a b))))
#'user/runner
user> (runner (fn [x y] (+ x y)))
0 0 0
0 1 1
0 2 2
1 0 1
1 1 2
1 2 3
2 0 2
2 1 3
2 2 4
This could also be written as (runner #(+ %1 %2) or even simply (runner +).
There is no need to pass "a" and "b" into the function as arguments. doseq and for introduce their own local, lexically scoped names for things. There's no reason they should use a and b; any name will do. It's the same for fn. I used x and y here because it doesn't matter.
I could've used a and b in the fn body as well, but they would have been a different a and b than the ones the doseq sees. You may want to read up on scope if this doesn't make sense.
I would make its signature be something like
(runner alen blen op)
example:
(runner 10 10 +)
I'm not really sure i'm answering the correct question. I'm thinking "if i pass a function a symbol instead of a value how can it use the value that symbol represents? is that close?
(def a 4)
(defn my-inc [x] (+ (eval x) 1))
user> (my-inc 'a)
5
I'm sure there is a more elegant way than using eval.
It isn't clear enough to me what you're trying to achieve, but the following is an answer to what I guess is your question:
user=> (declare a b)
#'user/b
user=> (defn runner [] (+ a b))
#'user/runner
user=> (binding [a 1 b 2] (runner))
3
user=> (binding [a 2 b 3] (runner))
5
Note that the above style is likely not what you ought to be doing. Ask a better question and we'll give you better answers.
Related
I am trying to implement the range function in clojure, but my implementation is returning an error that I cannot understand. Here it is:
(defn implement-range [a b] (
if (= a b)
(conj nil b)
((conj nil a) (implement-range (inc a) b))))
I am trying to do in a recursive way, it is not complete yet, since I am stuck with this error:
ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn user/implement-range
I think that it is a parentheses problem that I cannot see (I am a newbie in clojure :) ). Any ideas?
Thanks in advance for any help
EDIT:
I would like to return something like (1 2 3 4) if I call the function like this:
(implement-range 1 5)
You were close:
(defn implement-range [a b]
(if (>= a b)
'()
(conj (implement-range (inc a) b) a)))
(implement-range 0 5)
=> (0 1 2 3 4)
First, the main problem is that ((conj nil a) (implement-range (inc a) b)))) is attempting to call (conj nil a) as a function, with (implement-range (inc a) b) as the argument. I'm not entirely sure what you're trying to do here, but this definitely isn't what you want.
I made three changes:
You need to conj the current number to the result of the recursive call. This is "unsafe" recursion since the recursive call isn't in tail position, but while messing around, that's not a big deal. You'll want to use an alternate method though if you intend to use this for real.
If you enter a b that is larger than a, it will explode. I fixed this by changing the base case condition.
Your base case didn't make any sense. Once the recursion stops, you'll want to add to an empty list.
Just a side note, any time you see ((, little alarm bells should go off. This is often a sign of a problem, unless you're getting fancy and writing something like ((comp str inc) 1); where the first form in the expression evaluates to a function.
the simplest (and the most classic one) would be something like this:
(defn implement-range [a b]
(when (< a b)
(cons a (implement-range (inc a) b))))
user> (implement-range 1 20)
;;=> (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
I did some research and found that use conj this way does not make any sense. So I came up with this:
(defn implement-range [a b] (
if (= a b)
b
(flatten (list a (implement-range (inc a) b)))))
So if I call the function with the 1 4 parameters the result will be:
(1 2 3 4)
But, since I am trying to implement a function such like the range function, it needs to remove the last element yet.
EDIT 1
The final function that I wrote looked like this:
(defn implement-range [a b] (
if (= a b)
nil
(remove nil? (flatten (list a (implement-range (inc a) b))))))
EDIT 2
After some more research I've figured out another way to solve this, with less lines of code:
(defn new-range [a b]
(take (- b a) (iterate inc a)))
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.
From the clojure docs, the function *':
Returns the product of nums. (*') returns 1. Supports arbitrary
precision. See also: *
I understand the use cases for arbitrary precision as explained in the example provided:
;; great so it gives the same results as *.
;; not quite check this out
(* 1234567890 9876543210)
;; ArithmeticException integer overflow
(*' 1234567890 9876543210)
;;=> 12193263111263526900N
However, the (*') returns 1 does not seem to have any use at all since you can just specify the explicit value. In the same example provided:
;; there is an implicit 1
(*')
;;=> 1
;; the implicit 1 comes into play
(*' 6)
;;=> 6
I had thought that perhaps it would be useful if the second argument is not defined, perhaps nil but:
(*' 6 nil)
Throws a NullPointerException.
Why would you use (*' 6) over 6 and (*') over 1?
* and *' are equivalent in this regard:
first of all - how would you otherwise handle the [] and [x] cases in *?
The source as it is written makes the most sense and AFAIK is mathematicly correct (identity value and such).
user=> (source *)
(defn *
"Returns the product of nums. (*) returns 1. Does not auto-promote
longs, will throw on overflow. See also: *'"
{:inline (nary-inline 'multiply 'unchecked_multiply)
:inline-arities >1?
:added "1.2"}
([] 1)
([x] (cast Number x))
([x y] (. clojure.lang.Numbers (multiply x y)))
([x y & more]
(reduce1 * (* x y) more)))
second, it makes it much more robust in cases other then manually writing (* 2 4). I wouldn't write (*) to mean 1.
Like the following - see the single element and emtpy vector on pos 3 and 4.
user=> (map (partial apply *) [[2 2] [2 3 2] [6] []])
(4 12 6 1)
Usually the 0-arity of a function is useful for a reduction or for applying to lists. For example:
(apply *' (range 5))
The multiplicative identity is one.
In terms of code and clojure, birdspider and Alejandro C. both answered about the (apply * []) case, in which it is indeed useful for (*) to equal 1.
However, I want to point out another case where (*) is useful. When passed to transduce as a reducing function.
transduce docstring:
clojure.core/transduce
[xform f coll]
[xform f init coll]
Added in 1.7
reduce with a transformation of f (xf). If init is not
supplied, (f) will be called to produce it. f should be a reducing
step function that accepts both 1 and 2 arguments, if it accepts
only 2 you can add the arity-1 with 'completing'. Returns the result
of applying (the transformed) xf to init and the first item in coll,
then applying xf to that result and the 2nd item, etc. If coll
contains no items, returns init and f is not called. Note that
certain transforms may inject or skip items.
The relevant part here is "If init is not supplied, (f) will be called to produce it.".
So using * as the rf without an init value will use an init value of 1. Which is probably what you want.
Similarly (+) ;=> 0 (additive identity) and (conj) ;=> [].
I think this is a neat example of things coming together nicely, as (*) was decided long before transducers were a thing.
The default value (*) => 1 is there to avoid a NullPointerException in the event you don't know how many items you want to multiply. That is:
=> (apply * [1 2 3])
6
=> (apply * [3])
3
=> (apply * [])
1
=> (apply * nil)
1
=> (* nil)
nil
=> (*)
1
Wow! I am surprised! I couldn't force a NPE even when I tried!
I still think this behavior provides a false sense of security. If I am expecting to multiply some numbers and one (or more) are missing, I'd rather have the default be to detect the error via an Exception. As it is, the default is for Clojure to cover-up the error by being "helpful" and trying to guess what I may have meant.
Update
I did finally generate an NPE:
> (* 5 nil) => NullPointerException clojure.lang.Numbers.ops (Numbers.java:1013)
I find this even more surprising. If (* nil) => nil, I would have bet money that (* 5 nil) => nil would also be true. Strange!
I am working on the clojure koans and one of the questions in the functions needs further explanation for me to “get it” and have an aha moment. I am able to write the function that satisfies the question. But I don't fully understand why all the bits work.
Clojure> (= 25 ((fn [a b] (b a)) 5 (fn [n] (* n n))))
true
Question 1.
I do not understand why this throws an error:
Clojure> (= 25 ((fn [b a] (b a)) 5 (fn [n] (* n n))))
java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn
So the only change in the above is switching the order of b and a.
In my brain I read “a function that takes an a and b” or a “b and an a” but how they are used is up to the subsequent statement in the parens. Why does the order matter at this point?
Questions 2.
Clojure> (= 25 ((fn [a] (5 a)) (fn [n] (* n n))))
java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn
Why when I substitute out the value of b for the int it represents do I get an error?
Quentions 3.
((fn [a b] (b a)) 5 (fn [n] (* n n))))
Why does this not throw an error (b a) b in this instance is 5 which is a symbol.
The first item in brackets is expected to be a function or a special form unless it is a list?
look at your expression in the first function:
(b a)
since b is first, b has to be a function. In your second example, you're trying to pass 5 to b, but 5 is not a function. With descriptive names you can see that you're trying to use 5 as a function:
((fn [argument function] (argument function)) ;; problem!!
5
(fn [n] (* n n)))
Remember the evaluation rules for lisps: given this s-expression:
(f x y z)
evaluate f, x, y, and z, and apply f as a function to x, y, and z.
see answer to 1 -- '5' is not a function. Use descriptive names, and easily spot the problem:
((fn [function] (5 function)) ;; problem!!
(fn [n] (* n n)))
Change to:
((fn [a] (a 5)) ;; 'a' and '5' flipped
(fn [n] (* n n)))
to get this to run.
this isn't a problem: a is 5, b is a function in (b a). With descriptive names it makes more sense:
((fn [argument function] (function argument))
5
(fn [n] (* n n)))
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?