What is going on here:
(defn what [[a]]
(print a b))
now if I call (what "abid") I get:
a [1 2 3 4 5]
Where does this come from? what are the numbers?
You have b defined for sure before you define this function otherwise you would get
CompilerException java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:4:3)
try your code in new clojure repl with nothing else in it. And the b is source of that magic numbers.
E.G.:
(def b 5)
(defn what [[a]]
(print a b))
(what "abc")
a 5nil
Assuming b is defined as [1 2 3 4 5] somewhere, this is functioning exactly how I'd expect it to. Since b is otherwise undefined in the code you gave, we can only assume this is the case.
a is the first element of the first parameter to what. For (what "abcd"), this is the lower-case character "a".
Related
If I run a higher order function in the repl, or something that returns a function, like below, is there any way to later retrieve the returned function (the value that is returned by the repl) and evaluate it?
user> #(% 5 5)
#function[user/eval13160/fn--13161]
To explain the reason for the question, I'm playing around with http-kit, and ran the function run-server. It was only after execution that I realized that the function returns a function that is required to stop the server, and so I've been trying to figure how to use the function that was returned.
Yep, you can access previous REPL values with *1:
user=> #(% 5 5)
#object[user$eval3$fn__4 0x487db668 "user$eval3$fn__4#487db668"]
user=> (*1 +)
10
There's also *2 and *3 for trailing values from previous evaluations, and *e for prior exceptions.
You could also def the result:
(def my-fn #(% 5 5))
(def my-fn *1) ;; or do it later
I am really struggling to do this one function. The function is as follows
Write a function named no-divisors? which takes an input n. The function should return true if none of the numbers between 2 and βπ divide n, and false otherwise. The function should use both your get-divisors function and your divides? function.
Hint: you will probably need to wrap the divides? function in an anonymous function so that you can pass in the value of n.
This is my get-divisors function:
(defn get-divisors [n]
(str (range 2 (inc (Math/floor (Math/sqrt n))))))
This is my divides? function:
(defn divide [a b]
(zero? (mod a b)))
I have tried to create a method in order to try and complete this task, however, to no luck.
This is what I tried:
(defn no-divisors [n]
divide(n (get-divisors n)))
And I received the output:
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn user/x (form-init5516475059937019181.clj:16)`
I have an idea in mind which I would like to share of how I could create this task, however, since this is my first time using Clojure I am not too sure of to implement this function or if it is even possible. I am extremely sorry that I have mixed syntax, it's just I have never used Clojure up until this point, but here is my draft/blueprint:
(defn no-divisors [n]
resultsArray = []
def results((get-divisors n))
for results in get-divisors
resultsArray.append(results)
for i=results[0]; i< results.count; i++
divide(n i)
)
I maybe on the right path or probably (most likely) completely wrong. I am grateful and thankful for any/all help I can possibly receive. Just a side note, both my get-divisors and divides? functions work flawlessly.
Firstly, you can't just put parentheses anywhere in the code like you can in other languages. They mean something specific in Clojure (and other lisps) when evaluating code, namely the first thing in the list is a verb; a function to call. Nested brackets mean repeated calls to the result of a function. So if you have a function alice that returns a function, like this (stay with me, I'm trying to explain the error you're getting ;) ):
(defn alice []
(fn [] :bob))
then you can call it like this
(alice) ;; => #function[user/alice/fn--6930]
and it will return the function that you have created inside, and you can call that anonymous function like this:
((alice)) ;; => :bob
to actually get the result of that function. Apologies if this is a bit much off the bat, but the parens have meaning, and that's the cause of the error you're getting:
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn
This means that you're trying to call a number as a function. clojure.lang.IFn is Clojure's way of saying "the thing I was expecting was something that I could call as a function". By java.lang.Long, Clojure's mean's "number". ClassCastException means I saw one thing and was expecting the other. So really, what this error is trying to say is you wrote an open paren ( and followed that up with something named a number and not a function. That seems very much like you've written divide(n (get-divisors n)) instead of (divide n (get-divisors n)), because when evaluating divide(n (get-divisors n)) it first tries to evaluate divide and discovers this is a function, but doesn't try and call it. Then it looks at the next form (n (get-divisors n)) and tries asks what n is, and finds it's a number, which can't be called as a function. Make sense?
In your pseudo-code, you have an array that you append data to to collect the results while iterate through a loop to build the results. This is a very imperative way of approaching the problem, and not really the way Clojure is trying to encourage you to solve problems. Clojure tends to learn towards a more data focused way of solving the problem. One way to think about the problem is the way in which it's phrased in English. Given a number n, take all the numbers less than the square-root of it, and check if they divide into n. If that list is empty return true, otherwise return false. In Clojure you could write:
(defn divide? [a b]
(zero? (mod a b)))
(defn no-divisors? [n]
(->> (range 2 n)
(take-while #(< (* % %) n))
(filter (partial divide? n))
empty?))
Here, we use the ->> macro to take a lazy sequence of numbers between 2 and n, then limit that sequence using take-while to only the ones where the square of the number is less than n. Then we check that each one divides into n using the divide? function, and finally ask if the list is empty?. Since Clojure's sequences are lazy, no actual computation occurs until we try to evaluate the result using empty? which will stop when it reaches an element in the sequence. This makes it more efficient than actually traversing the whole list for large values of n.
Hope this helps.
P.S. I'm not sure your implementation of get-divisors is quite correct.
You must test your work as you go along. Let's look at your get-divisors function:
(defn get-divisors [n]
(str (range 2 (inc (Math/floor (Math/sqrt n))))))
Let's try it:
=> (get-divisors 20)
"(2 3 4)"
This is a string of characters, not the collection of numbers it ought to be. Remove the damaging str call:
(defn get-divisors [n]
(range 2 (inc (Math/floor (Math/sqrt n)))))
Now
=> (get-divisors 20)
(2 3 4)
Good. And an edge case, just to make sure:
=> (get-divisors 16)
(2 3 4)
Good again! We can use this function with some confidence.
Now we want to find out whether something is true of none of this collection. There's a handy function called not-any? that does this. For example,
=> (not-any? even? (range 1 100 2))
true
What we want to determine is whether none of the potential divisors of n actually divide n. So the shape of the function might be ...
I have been playing around with clojure for some time.But not able to figure out the difference between ~ vs normal reference.
For eg:
(defn f [a b] (+ a b))
(f 1 2)
outputs:
3
and on the other hand:
(defn g [a b] `(+ ~a ~b))
(g 1 2)
outputs:
(clojure.core/+ 1 2)
So my question is what's need for different syntax ?
There is a language feature called "syntax-quote" that provides some syntactic shortcuts around forming lists that look like clojure expressions. You don't have to use it to build lists that are clojure s-expressions, you can build what you want with it, though it's almost always used in code that is part of a macro. Where that macro needs to build a Clojure s-expression and return it.
so your example
(defn g [a b] `(+ ~a ~b))
when it's read by the Clojure reader would run the syntax-quote reader macro (which is named `)
and that syntax-quote macro will take the list
(+ ~a ~b)
as it's argument and return the list
(+ 1 2)
because it interprets symbol ~ to mean "include in the list we are building, the result of evaluating this next thing".
The backquote symbol ` and the tilde ~ are normally only used when writing macros. You shouldn't normally use them when writing normal functions using defn etc.
You can find more information here and in other books.
Very new to clojure so might be a noob question but here it is. So I read that the -> macro will invoke functions in sequence and I understand how this works.
(-> (+ 1 2) (* 10)) which results in 30
But why does this not do the same?
(defn testing-> [a b]
(list a b)
first)
This returns a function first and not "a" when called as (testing-> "a" "b"). What am I missing here? Using it in the wrong way?
the -> needs to be in the body of the function. it's not magic attributed to functions ending with -> but literally a macro whose name is -> which takes a sequence of things to do and produces a new expression with the same things nested each inside the next:
(defn testing [a b]
(-> [a b]
list
first))
in this exampel, when the -> macro runs it produces a new expression which looks like:
(defn testing [a b]
(first (list [a b])))
For another example, when you call -> with the arguemnts (+ 1 2) (* 10) it returns the expression (* (+ 1 2) 30) which is then evaluated as normal Clojure code.
PS: a macro is a function which takes a Clojure expression and produces another Clojure expression. These run In the middle of the compilation cycle and you can see what they are doing with the macroexpand-1 function.
A macro is something that restructures its input before it gets compiled.
user> (macroexpand '(-> (+ 1 2) (* 10)))
(* (+ 1 2) 10)
testing-> is a function, not a macro, so it does not restructure the input. You would need to rearrange the input forms before evaluation to get a behavior similar to ->. Every valid form needs to be translated into the standard clojure syntax at compile time, which is done via reader-expansion and macro-expansion.
Macro construction uses standard Clojure functions, but the semantics are somewhat unique (a macro should return the form that will be used at runtime). You can use the clojure.repl/source macro to see how various macros are implemented.
Any operations you need can be expressed as functions, and general creating macros should be avoided unless you need a new syntax.
βI'm new to cloβjβure. What is the difference between β(β3β) and just 3β? If I do β(3) βI get this exception:
java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFnββ.
3 is literal number 3.
(3) is a a function application, you are trying to call function 3 with no parameters. (There's no such function and it seems you can't define it.)
'(3) is a list of one item, 3. It's the same as (list 3), which is a function application.
Here is a repl session:
repl=> 3
3
repl=> (3)
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn repl/eval1388 (NO_SOURCE_FILE:1)
repl=> '(3)
(3)
repl=> (list 3)
(3)
repl=> => (defn 3 [] 3)
ClassCastException java.lang.Long cannot be cast to clojure.lang.IObj clojure.core/with-meta (core.clj:211)
In lisps parenthesis mean function application, so this:
(a b c d)
means apply a to arguments b c d
You're trying to apply 3, which is not a function, nor can it be converted to one.
In Clojure, parentheses mean function application. (3) is trying to call a function named 3, which doesn't exist.
When you start with a Lisp you have to get used to the fact that parenthesis are significative. You can't just add more parenthesis in hope to disambiguate operator priorities β however since everything is in prefix form there's no operator ambiguity.
Once you get used to the fact that all parenethesis matter, try to mentally move the opening one one item to the right, e.g. (println "hello")becomes println("hello").
Since the language is very regular it implies that (3) should be read as 3(). 3 is not a function thus you can't call it.