I'm learning clojure and have a very basic question: given that clojure has type inference, how can you tell what class was inferred?
For instance, these would each result in different data types:
(2)
(/ 2 3)
(/ 2.0 3)
Is there some kind of class function that will return the data type? Also, is there a normal way of casting something to be a specific type? So in the second example above, what would I do if I wanted the result to be float?
There is a type function in the clojure.core library.
user> (type 2)
java.lang.Integer
user> (type (/ 2 3))
clojure.lang.Ratio
user> (type (/ 2.0 3))
java.lang.Double
If you want to convert a given number into a float then use float.
user> (float 10)
10.0
Similarly you may not need to cast because the following works:
user> (Double/toString (/ 2 3))
"0.6666666666666667"
However, this does too:
user> (str (/ 2 3))
"0.6666666666666667"
Related
Is there any way to prevent clojure from making for example a 2/5 from 6/15? I need for a function to have the original denominators of ratios, hence the question.
There is no way to prevent clojure from making 2/5 from 6/15. This is most readily apparent from the equality of clojure.lang.Ratio defined here. Preserving the original unreduced version would break equality.
This sounds like a datatype problem. You are putting information into a type that doesn't preserve the amount of data that you need. Fundamentally you are putting two numbers into a ratio datatype which is a single scalar value. You'll (most probably) need to thread more information through or delay the conversion into a ratio.
The calculation of GCD is not conditional:
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java#L355
You can create a clojure.lang.Ratio type directly:
user=> (def x (clojure.lang.Ratio.
(java.math.BigInteger. "6") (java.math.BigInteger. "15")))
user=> (type x)
clojure.lang.Ratio
user=> x
6/15
But compareTo assumes the reduction has occurred and checks the numerator and denominator values individually:
user=> (def y (/ 6 15))
#'user/y
user=> (type y)
clojure.lang.Ratio
user=> y
2/5
user=> (= x y)
false
And other operations will wind up reducing:
user=> (* 3 x)
6/5
user=> (* 3 y)
6/5
Strange requirement. A simple solution is NOT to calculate, i.e. store them as is
{:n 6 :d 15}
The only time you calculate is at the end, when you want a result, or if you want to check for equal.
I saw the usage of & in Clojure function signature like this (http://clojure.github.io/core.async/#clojure.core.async/thread):
(thread & body)
And this:
(doseq seq-exprs & body)
Does that means the function/macro can accept a list as variable? I also find * is often used to mean multiple parameters can be accepted, like this:
(do exprs*)
Does anyone have ideas about the difference between & and * in function/macro signature? Is there any documentation to explain this syntax?
It means that there can be multiple parameters after the ampersand, and they will be seen as a seq by the function. Example:
(defn g [a & b]
(println a b))
Then if you call:
(g 1 2 3 4)
it will print out 1 (2 3 4) (a is 1, b is a sequence containing 2, 3 and 4).
In clojure binding forms (let, fn, loop, and their progeny), you can bind the rest of a binding vector to a sequence with a trailing &. For instance,
(let [[a b & xs] (range 5)] xs) ;(2 3 4)
Uses of * and other uses of & are conventions for documenting the structure of argument lists.
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 see this behavior in Clojure 1.2.1:
user=> (type '(1 2))
clojure.lang.PersistentList
user=> (type `(1 2)) ;; notice syntax-quote
clojure.lang.Cons
user=> (type '(1))
clojure.lang.PersistentList
user=> (type `(1))
clojure.lang.PersistentList
I expected `(1) to be a Cons just like `(1 2) is.
I also tried:
user=> (type (cons 1 nil))
clojure.lang.PersistentList
user=> (type (cons 1 `()))
clojure.lang.Cons
user=> (type (cons 1 '()))
clojure.lang.Cons
user=> (type (cons 1 []))
clojure.lang.Cons
So what is the reason for `(1) and (cons 1 nil) to be PersistentLists?
Like amalloy says, you shouldn't program against those exact types but against the seq abstraction.
However, I think I can take a guess at the reason. The Clojure forms that produce a PersistentList ultimately call RT.java, specifically the cons(Object x, Object coll) method. It begins with a pretty odd check: if(coll == null) return new PersistentList(x), after which it creates a Cons object if that check doesn't pass. If you look at earlier versions of the code, you can find this:
static public IPersistentCollection cons(Object x, IPersistentCollection y) {
if(y == null)
return new PersistentList(x);
return y.cons(x);
}
So in an earlier version of the function, the call was dispatched to the cons method of the second argument, so the case when the second argument was null (i.e. nil in Clojure) needed special handling. Later versions don't do that dispatching (or actually do it but in a different way, presumably to support a larger variety of collection types), but the check has been retained since it does not break any correctly written code.
If you care about the difference, your program is incorrect. They're both seqs, in the sense that (seq? x) returns true; the rest is implementation details you shouldn't depend on.
The following expression in clojure works great:
(doseq [x '(1 2 3 4)] (println x))
This one gives me a nullpointer:
(doseq [x '(1 2 3 4)] ((println x)(println "x")))
It produces the following output:
user=> (doseq [x '(1 2 3 4)] ((println x)(println "x")))
1
x
java.lang.NullPointerException (NO_SOURCE_FILE:0)
user=> (.printStackTrace *e)
java.lang.NullPointerException (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4639)
at clojure.core$eval__5182.invoke(core.clj:1966)
at clojure.main$repl__7283$read_eval_print__7295.invoke(main.clj:180)
at clojure.main$repl__7283.doInvoke(main.clj:197)
at clojure.lang.RestFn.invoke(RestFn.java:426)
at clojure.main$repl_opt__7329.invoke(main.clj:251)
at clojure.main$legacy_repl__7354.invoke(main.clj:292)
at clojure.lang.Var.invoke(Var.java:359)
at clojure.main.legacy_repl(main.java:27)
at clojure.lang.Repl.main(Repl.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at jline.ConsoleRunner.main(ConsoleRunner.java:69)
Caused by: java.lang.NullPointerException
at user$eval__266.invoke(NO_SOURCE_FILE:26)
at clojure.lang.Compiler.eval(Compiler.java:4623)
... 14 more
nil
Just adding an extra set of parentheses around the body of a doseq gives me that nullpointer.
What am I doing wrong?
Well, you already figured out the solution, so just a few hints to explain the behavior:
In Clojure (just like in Lisp, Scheme, etc) everything is an expression and an expression is either an atom or a list. With regard to lists, the Clojure manual says
Non-empty Lists are considered calls
to either special forms, macros, or
functions. A call has the form
(operator operands*).
In your example, the body ((println x) (println x)) is a list and the operator is itself an expression which Clojure has to evaluate to obtain the actual operator. That is, you're saying "evaluate the first expression and take its return value as a function to invoke upon the second expression". However, println returns, as you noticed, only nil. This leads to the NullPointerException if nil is interpreted as an operator.
Your code works with (do (println x) (println x)) because do is a special form which evaluates each expression in turn and returns the value of the last expression. Here do is the operator and the expressions with println ar the operands.
To understand the usefulness of this behavior, note that functions are first-class objects in Clojure, e.g., you could return a function as a result from another function. For instance, take the following code:
(doseq [x '(1 2 3 4)] ((if (x > 2)
(fn [x] (println (+ x 2)))
(fn [x] (println (* x 3)))) x))
Here, I am dynamically figuring out the operator to invoke upon the element in the sequence. First, the if-expression is evaluated. If x is larger than two, the if evalutes to the function that prints x + 2, else it evaluates to the function that prints x * 3. This function is than applied to the x of the sequence.
I see you've already realised the problem, however please note you don't need a do:
(doseq [x '(1 2 3 4)] (println x) (println "x"))
doseq is (as the name suggests) a do already :)