This question already has answers here:
Using interop constructor in map function(Clojure)
(2 answers)
Closed 8 years ago.
(Integer. "1") ; => 1
(map Integer. ["1" "2"])
; CompilerException java.lang.ClassNotFoundException: Integer., compiling:(/tmp/form-init6181502527198258116.clj:1:1)
What am I doing wrong here or is there some kind of gotcha?
Integer. is the same as new Integer. You want:
(map #(Integer. %) ["1" "2"])
Related
This question already has an answer here:
Wrong number of args (0) passed to: PersistentVector on loop/recur function
(1 answer)
Closed last year.
I'am new to clojure and i wrote this func:
(def fact (fn [n] (
(apply * (drop 1 (range n))))))
When calling it i get the error:
ClassCastException class java.lang.Long cannot be cast to class clojure.lang.IFn (java.lang.Long is in module java.base of loader 'bootstrap'; clojure.lang.IFn is in unnamed module of loader 'app') my-stuff.core/fact (form-init3352210926102455316.clj:18)
Why?
You've got an extra parenthesis around apply:
(def fact (fn [n]
(apply * (drop 1 (range n)))))
There's extra pair of parentheses- when you call for example (fact 3), result will be (2) (not list, but call of function) and 2 isn't function, so it throws error.
When you remove these parentheses, like this:
(def fact (fn [n]
(apply * (drop 1 (range n)))))
, call (fact 3) returns 2- but is this result correct? If you want to return factorial for given number, you have to use range correctly:
(defn fact [n]
(->> (range 1 (inc n))
(apply *)))
(->> is thread-last macro)
Example:
(fact 3)
=> 6
This question already has answers here:
Generating a symbol from a string and applying it as a function
(2 answers)
How to convert a string to a function in Clojure?
(2 answers)
clojure resolving function from string name
(1 answer)
Call functions read from EDN files
(1 answer)
Closed 2 years ago.
The following works:
((resolve (symbol "first")) [1 2 3])
;; => 1
Why is it wrong to think that,
((read-string "first") [1 2 3])
;; => nil
should work, but it doesn't? (I get nil.)
The return value from (resolve (symbol "first")) is probably the Var clojure.core/first which gets applied to the arguments.
The return value from (read-string "first") is the symbol first which also gets applied to the arguments. But using a symbol as a function has a different meaning. The argument is expected to be a map and the returned value is the equivalent of doing (get a-map the-symbol).
Any type that implements the clojure.lang.IFn can be in the function position. The reason why using a symbol as a function with a vector argument returns nil instead of failing, lies in the implementation details of IFn for the Symbol type (in this particular case for the arity 1):
public Object invoke(Object obj) {
return RT.get(obj, this);
}
RT.get() checks if obj implements ILookup and calls ILookup.valAt() if it does. Clojure vectors do implement ILookup but they expect an integer as the provided key and return nil for anything else.
public Object valAt(Object key, Object notFound){
if(Util.isInteger(key))
{
int i = ((Number) key).intValue();
if(i >= 0 && i < count())
return nth(i);
}
return notFound;
}
public Object valAt(Object key){
return valAt(key, null);
}
Juan is correct:
(resolve (symbol "first")) => <#clojure.lang.Var #'clojure.core/first>
(read-string "first") => <#clojure.lang.Symbol first>
We can verify:
(ns tst.demo.core
(:use tupelo.core tupelo.test))
(dotest
(let [first-var (var clojure.core/first)
first-sym (symbol "first")]
(is= 1 (first-var [1 2 3])) ; automatically converted from a var => funciton by Clojure
(is= nil (first-sym [1 2 3]))))
Please also see this answer for more information on the double-indirection of a Clojure Var object.
This question already has answers here:
Function-local, self-referential, lazy fibonacci sequence
(5 answers)
Closed 7 years ago.
Cause I have a lazy-seq to calculate fibonacci sequence.
(def fibonacci
(lazy-cat [0 1] (map + fibonacci (rest fibonacci))))
=> #'user/fibonacci
(take 10 fibonacci)
=> (0 1 1 2 3 5 8 13 21 34)
But when I try to put fibonacci into let
(let [fibonacci
(lazy-cat [0 1] (map + fibonacci (rest fibonacci)))]
(take 10 fibonacci))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: fibonacci in this context, compiling:...
How to solve it?
Unlike with def, the binding of x to f made by (let [x f] ...) is not visible inside f. More precisely, binding to x is done after evaluating f. In order to have recursive definitions, you need to use letfn, which is for defining functions. Consequently, you can no longer treat fibonacci as a LazySeq, but you can define it as a function returning a LazySeq:
(letfn [(fibonacci []
(lazy-cat [0 1] (map + (fibonacci) (rest (fibonacci)))))]
(take 10 (fibonacci)))
It looks like if you want this construction to work in let, then you won't be able to write such type of code:
(defn override-variables [x]
(let [x (do-some-stuff-with x)]
(do-stuff x))
And this situation is much more frequent that defining lazy sequences in terms of variables in locals.
But you can call anonymous function in it's body if you give the name to it with (fn fib-func [args] ...) and construct lazy-seq in terms of functions, not variables.
(let [fib ((fn rfib [a b]
(lazy-seq (cons a (rfib b (+ a b)))))
0 1)]
(take 10 fib))
This question already has answers here:
How do I avoid Clojure's chunking behavior for lazy seqs that I want to short circuit?
(3 answers)
Closed 8 years ago.
This code:
(first (map (fn [d]
(apply * (repeat d 10)))
(range)))
yealds an integer overflow exception, while this code:
(first (map (fn [d]
(apply * (repeat d 10)))
(range 0 1)))
yealds 1.
Both codes should yeald 1 but for some reason the laziness of range has a strange behaviour. It seems to get chuncks of data instead of only one at a time. Is it possible to make range behave in the desired way?
range is chunked, as a performance optimization. There are a few ways to fix this including using (iterate inc 0) or unchunk (there are a few versions, this one is copied from math.combinatorics)
(defn unchunk
[s]
(lazy-seq
(when (seq s)
(cons (first s)
(unchunk (rest s))))))
user=> (first (map (fn [d]
(apply * (repeat d 10)))
(unchunk (range)))
1
This question already has answers here:
Clojure: Semi-Flattening a nested Sequence
(5 answers)
Closed 8 years ago.
Is there a clojure function to do:
((1 2) (3) (5 1) (2)) => (1 2 3 5 1 2)
(def a-list '((1 2) (3) (5 1) (2)))
(my-func a-list)
;; =>(1 2 3 5 1 2)
(apply concat a-list) ;; (1 2 3 5 1 2)
(flatten a-list)
will do the trick as well.
See:
http://clojuredocs.org/clojure_core/clojure.core/apply
http://clojuredocs.org/clojure_core/clojure.core/concat
http://clojuredocs.org/clojure_core/clojure.core/flatten