Clojure - function or cons? - clojure

OK, a fibonacci function in Clojure:
(defn give-fibs []
((fn fib-seq [a b]
(cons a (lazy-seq (fib-seq b (+ a b)))))
0 1))
Now, my question is, when I call it like so, I get an error :
(take 10 give-fibs)
edit, error is - java.lang.IllegalArgumentException: Don't know how to create ISeq from: four_cloj.core$give_fibs
However, it works when I call:
(take 10 (give-fibs))
When I check out what's going on, I can't really explain it:
(class (give-fibs)) ; clojure.lang.Cons
(class give-fibs) ; four_cloj.core$give_fibs
??

give-fibs is just that - the function itself. The concept of a function as a value that can be passed around (for example, as argument to take) takes some getting used to, but it's perfectly sensible and normal.
(give-fibs) is the result of calling give-fibs with no arguments, which is what you want in this context. The result is a list, and each element of a list is a Cons object, which is what class tells you.

In this expression you don't really call give-fibs:
(take 10 give-fibs)
you just pass the function itself to take. What you want is to actually call give-fibs in order to pass result of it to take:
(take 10 (give-fibs))

Remember that the first element in an s-expression is considered to be in function position, that is to say it will be executed. Therefore give-fibs and (give-fibs) are different in that the former is the actual function being passed to take and the latter is calling that function, and therefore returning the result to be passed to take.
Thats why (class give-fibs) is a function, and (class (give-fibs)) is a Cons cell as expected.
Just remember the first var after an opening bracket is in function position and will be executed, and its perfectly valid to pass an unexecuted function to another.

Related

Clojure - Creating a No Divisors function

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 ...

Declare dummy (unused) parameters for Clojure anonymous function

As also explained in the answers of this question, Clojure determines the number of parameters of an anonymous function (defined through #()), by the maximal parameter index referenced in the body (e.g. if the maximal referenced parameter is %4, then that anonymous function has 4 parameters).
Question: is there some syntax to tell the Clojure compiler that an anonymous function expects one parameter, even not referencing that parameter? Or, in this case, the only "clean way"* is to use the fn syntax? (* "Clean way": I'm aware that in most cases, you could reference the dummy parameter without affecting the function -- see below, but I would like to avoid such workarounds.)
My use case: I have a function (defn foo [predicate]), where predicate expects exactly one argument, and I would like to test foo with a predicate that always returns true. (I.e., something like #(true).) This causes an ArityException since the interpreter thinks that #(true) expects zero arguments.
In this particular case, I could use some clever hack like #(or true %), but:
It is almost as much to type as the fn-variant.
I'm interested if there is a generic solution.
Edit: so to be clear, I'm looking for something like this:
#[1](true) ;; the anonymous function takes one parameter
No. Just use fn. That's what it's for.
If it's a constant return you are after you can use constantly:
(map (constantly 10) '(1 2 3 4 5))
; ==> (10 10 10 10 10)
If it's not you can use fn with a rest argument:
(fn [& _]
some-side-effect-expression)
; ==> non functional value
In fact this can be done on higher order functions where you don't need all the passes arguments:
(some-fun (fn [a b & _] (+ a b)) '(1 2 3 4 5))
; ==> (3 5 7 9)
If you insist on the #( ... ) syntax, you can write
#(do % true)
... incurring no run-time penalty, whatever you want to return.
But (constantly true), as #Sylvester suggests, is idiomatic, and accepts any argument list:
((constantly true) 1 2 "Buckle my shoe");true

Lazyness and stackoverflow

I wrote the following:
(fn r [f xs]
(lazy-seq
(if (empty? xs)
'()
(cons (f (first xs)) (r f (rest xs))))))
to solve 4clojure.com's problem #118: http://www.4clojure.com/problem/118
which asks to reimplement map without using map etc. and that solution passes the tests (I don't know if it's correct or not: it's very close to other solutions that said).
Because the problem stated that it had to be lazy I wrote the code above by "wrapping" my solution in a lazy-seq... However I don't understand how lazy-seq works.
I don't understand what is "lazy" here nor how I could test it out.
When I ask (type ...) I get, unsurprisingly, a clojure.lang.LazySeq but I don't know what's the difference between that and what I get if I simply remove the lazy-seq "wrapping".
Now of course if I remove the lazy-seq I get a stackoverflow why trying to execute this:
(= [(int 1e6) (int (inc 1e6))]
(->> (... inc (range))
(drop (dec 1e6))
(take 2)))
Otherwise (that is: if I let the lazy-seq wrapping in place), it seems to work fine.
So I decided to try to somehow "debug" / trace what is going on to try to understand how it all works. I took the following macro (which I found on SO IIRC):
(defmacro dbg [x] `(let [x# ~x] (println "dbg: " '~x "=" x#) x#))
And wrapped the working version inside the dbg macro and tried to execute it again. And now kaboom: the version which worked fine now throws a stackoverflow too.
Now I'm not sure: maybe it's an unwanted effect of the macro that would somehow force the evalution of stuff that otherwise wouldn't be evaluated?
It would be great if anyone could explain, using this simple function and the simple test, how lazyness does work here, what exactly gets called when, etc.
The whole magic lies in clojure.lang.LazySeq java class. Which itself implement the ISeq interface and the s-expressions parameter to the lazy-seq macro are converted to a function without any parameter and is passed to the constructor of clojure.lang.LazySeq (to the constructor which take IFn object as parameter) and because in the end you have called r function again (which is returning a ISeq and not the complete list) this allows the LazySeq to evaluate items lazily.
So basically the flow goes something like this:
LazySeq calls the Fn passed to it (i.e the rest body of the code)
This Fn call returns a ISeq because Lists implements ISeq. This return ISeq (list) with first value as a concrete value and second is a LazySeq object due to recursive call to r. This returned ISeq is stored in a local variable in the class.
The ISeq implementation of LazySeq on calling next item does call the next of ISeq (list) that it stored in local class variable in above step and check if it is of type LazySeq (which it will be in 2nd item due to r call), if it is LazySeq then evaluate that and return then item else return the item directly (the first concrete value that you passed to cons)
I know it is a little mind bending thing :). I also went through the Java code just now and was able to figure out after I realized that the magic is possible because the recursive call to r itself return a lazy sequence. So there you have it, kind of custom delimited continuations :)

Clojure can't pass list to a function Error PersistentList cannot be cast to clojure.lang.IFn

I have a few functions that deal with lists. I have an even function which accepts a list parameter and gets the even indexes of the list. The odd function does the same thing but with odd indexes. I also have another function that merges two sorted lists called merge-list that takes two lists as parameters.
The problem is with the function I am writing now: merge-sort.
Here is what I have:
(defn merge-sort [lis]
(if (empty? (rest lis))
lis
(merge-list (merge-sort (odd(lis))) (merge-sort (even(lis))))))))
For some reason I keep getting the error
java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
I can pass the odd function rest lis like this (odd(rest lis)) (same with even). It runs fine but that obviously doesn't give me the solution I want.
I'm very new to Clojure so any tips would be appreciated. Thanks.
(odd lis) and (even lis), not (odd (lis)). You want to pass it as a parameter, not call it as a function and then pass the result of that.
When the Clojure compiler encounters a list, it looks at the head of the list for a function or macro to invoke.
The error message "FooClass cannot be cast to clojure.lang.IFn" usually means that you have an instance of FooClass in "function position" (the head of a list) which is neither a function nor a macro.
Often this is caused by a syntax error or a buggy macro. If, as amalloy suggests, you are wrapping your list argument in parentheses, then that is the problem.

When to use `constantly` in clojure, how and when are its arguments evaluated?

In the accepted answer to another question, Setting Clojure "constants" at runtime the clojure function constantly is used.
The definition of constantly looks like so:
(defn constantly
"Returns a function that takes any number of arguments and returns x."
{:added "1.0"}
[x] (fn [& args] x))
The doc string says what it does but not why one would use it.
In the answer given in the previous question constantly is used as follows:
(declare version)
(defn -main
[& args]
(alter-var-root #'version (constantly (-> ...)))
(do-stuff))
So the function returned by constantly is directly evaluated for its result. I am confused as to how this is useful. I am probably not understanding how x would be evaluated with and without being wrapped in `constantly'.
When should I use constantly and why is it necessary?
The constantly function is useful when an API expects a function and you just want a constant. This is the case in the example provided in the question.
Most of the alter-* functions (including alter-var-root) take a function, to allow the caller to modify something based on its old value. Even if you just want the new value to be 7 (disregarding the old value), you still need to provide a function (providing just 7 will result in an attempt to evaluate it, which will fail). So you have to provide a function that just returns 7. (constantly 7) produces just this function, sparing the effort required to define it.
Edit: As to second part of the question, constantly is an ordinary function, so its argument is evaluated before the constant function is constructed. So (constantly #myref) always returns the value referenced by myref at the time constantly was called, even if it is changed later.