Why aren't my if statements working? - list

I'm extremely new to Clojure and very new to functional programming. I'm expecting this to return True or False but it's just infinitely recursing and it doesn't seem to be hitting true at all.
My test data set is this:
(def y (list 1 2 3 4)) ; and I'm passing in 2 for X.
(defn occursIn [x y]
(if (= y nil)
"False"
(if (= x first y )
"True"
(occursIn x (rest y))
)
)
)

Try this, and please pay attention to the recommended way to format your code - don't leave lonely parentheses on a line by themselves, they're not like {} in other programming languages:
(defn occursIn [x y]
(if (empty? y)
"False"
(if (= x (first y))
"True"
(occursIn x (rest y)))))
You forgot to call first on the y list, like this:
(first y)
Also, notice that the base case isn't working as you expected. Use this test instead:
(empty? y)
For completeness' sake, here's a more idiomatic way to write the same procedure - but beware of the edge case pointed by #omiel in the comments, this won't work if x is false or nil:
(defn occursIn [x y]
(if (some #(= x %) y)
"True"
"False"))
An even better solution, free from the edge case - as suggested by #mange in the comments:
(defn occursIn [x y]
(if (every? #(not= x %) y)
"False"
"True"))

Oscar's answer is correct and helpful, but I just thought I'd provide an alternate answer which demonstrates how to make a function which is closer to your original function, while still being relatively idiomatic clojure:
(defn occurs-in [needle haystack]
(if-let [[head & tail] (seq haystack)]
(if (= needle head)
"True"
(recur needle tail))
"False"))
In this case I've:
used destructuring to extract head/tail instead of using first/rest on a sequence.
used if-let to bind those names only if haystack is non-empty (that is, if (seq haystack) is truthy).
used recur instead of occurs-in to ensure that this function will be compiled to use tail call elimination, so it calls itself again without using an additional stack frame.
This may not be an issue for small inputs, but it's essential to make it work for calls like (occurs-in 1000000 (range))
In terms of idiomatic naming, see that I've used occurs-in instead of occursIn: generally lisps use hyphens (lisp-case) instead of camel case (camelCase) for names.

Before we do anything else, let's replace "True" with boolean true and "False" with boolean false. The reason for doing this will become apparent.
The fundamental problem is that rest never returns nil. It returns the empty list () instead. And (rest ()) is (). So you get an endless sequence of recursive calls that ultimately blow the top off the stack.
next does return nil where rest returns (). So use next instead of rest and at least we get an answer:
(def aList (list 1 2 3 4))
(defn occursIn [x y]
(if (= y nil)
false
(if (= x first y)
true
(occursIn x (next y))
)
)
)
(occursIn 2 aList)
; false
... but the wrong answer. Why? As #OscarLopez says, you are missing parentheses around first y to call first upon the argument y. As it stands,
(= x first y)
tests whether x, first, and y are all equal. There is only one way this can happen:
(occursIn first first)
; true
... not what we want. So, let's call first instead of comparing it:
(defn occursIn [x y]
(if (= y nil)
false
(if (= x (first y))
true
(occursIn x (next y))
)
)
)
(occursIn 2 aList)
; true
It works.
Actually, the base case does work:
(occursIn 2 ())
; false
... but only because the next call turns () into nil: queasy.
And it does misfire searching for nil:
(occursIn nil ())
; true
... because (first ()) returns nil and nil pretends to be () when asked to be a sequence (this is called nil punning), so (first nil) is nil.
So, again following Oscar, we had better test whether y is empty, not whether it is nil:
(defn occursIn [x y]
(if (empty? y)
false
(if (= x (first y))
true
(occursIn x (next y))
)
)
)
(occursIn nil ())
; false
The logic is now correct. Let's make it clearer by using and and or instead of ifs with explicit true and false results (a code smell, in my view):
(defn occursIn [x y]
(and (not (empty? y))
(or (= x (first y))
(occursIn x (next y))
)
)
)
The code reads easily now. It is to do this that we used the proper boolean values.
Only two more changes:
If you look up empty?, you'll find that (empty? y) means (not
(seq y)), so (not (empty? y)) means (not (not (seq y))), which is
equivalent to (seq y).
The recursive call to occursIn is the last thing that happens: it
is said to be in tail position. We can therefore replace it by
recur. This consumes no stack, so puts no limit on the length of
the sequence that can be searched.
So we end up with ...
(defn occursIn [x y]
(and (seq y)
(or (= x (first y))
(recur x (next y))
)
)
)

Related

How is this code with reduce function evaluating in Clojure?

Following is the Clojure code:
(reduce (fn [r x] (if (nil? x) r (conj r x)))
[]
[:mouse nil :duck nil :lory nil])
In REPL, it evaluates to [:mouse :duck :lory].
My question is, how is the code evaluating?
According to me, r is [] and x is [:mouse nil :duck nil :lory nil]. nil? x is false as so it evaluates to (conj r x). But x is a vector, not an element so how it will add an element to the empty vector r in conj? I don't know but I am wrong somewhere in my approach. The output is the animals' name vector without nil values.
Can anyone please explain me the execution of code. Thanks.
Your problem appears to be understanding how reduce works. I'd like to refer you to the source code, but it simply maps onto a Java implementation, so I have to fake it.
The kind of reduce you are doing - supplying the initial value - might have been coded as follows:
(defn reduce [f init coll]
(loop [acc init, tail coll]
(if (seq tail)
(recur (f acc (first tail)) (rest tail))
acc)))
As you can see, it works through the sequence coll, applying the function f to acc and the first value in the sequence, to generate a new acc. When there is no more sequence, it returns acc.
How does this apply to your example? The reducing function ...
(fn [r x] (if (nil? x) r (conj r x)))
... ignores nil xs but conjs anything else onto the end of the accumulating vector r. Your code is more or less equivalent to ...
(remove nil? [:mouse nil :duck nil :lory nil])
=> (:mouse :duck :lory)
... except you get a lazy sequence instead of a vector.
Courtesy of FredOverflow's Clojure Transducers from the ground up you can wrap the reducing fn in this logging function to print the different arguments (r and x) to every step:
(defn logging [f]
(fn [& args]
(prn args)
(apply f args)))
(reduce (logging (fn [r x] (if (nil? x) r (conj r x))))
[]
[:mouse nil :duck nil :lory nil])
user=> ([] :mouse)              ([:mouse] nil)             ([:mouse] :duck)             ([:mouse :duck] nil)             ([:mouse :duck] :lory)             ([:mouse :duck :lory] nil)
So only the keywords are added (not nils), starting with []. At the end [:mouse :duck :lory] is returned.

Null pointer exception when executing loop in clojure

(defn my-loop [x]
(cond (> x 1)
((println x)
(my-loop (- x 1)))
)
)
;; => #'user/my-loop
user> (my-loop 10)
Why do i get a null pointer exception, when executing this function?
Is this not a normal recursion?
You are invoking the return of (println x) with the additional layer of parentheses. println returns nil so invoking it will lead to the NullPointerException.
To evaluate more than one form where only one is expected use the do special form, which evaluates any number of forms and returns the value of the last one:
(defn my-loop [x]
(cond (> x 1) (do
(println x)
(my-loop (- x 1)))))
In this case, when can replace a one armed cond and do
(defn my-loop [x]
(when (> x 1)
(println x)
(my-loop (- x 1))))
The code should typically look something like so:
(defn my-loop
"Some docstring"
[x]
(cond
(> x 1) (println x)
:else (my-loop (- x 1))))
Keeping to good formatting helps to see problems early.
You may also be interested in this list of documentation sources, especially the Clojure CheatSheet & the book "Getting Clojure".

Cannot pass list as argument to function

I have a substitute function that will take in an expression such as (or false x y) and a binding map such as '{x false, y true} and will return the list with the appropriate substitutions. The result is in l and displayed. How might I pass l into another function to do some other processing? The definition for the function I'm passing to looks like this:
(defn f [expression]
)
I have tried passing l as a parameter when calling f, but I get the following error:
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:550)
Here is my substitute function:
(defn deep-substitute [m l]
(map (fn [i]
(if (seq? i)
(deep-substitute m i)
(m i i)))
l
(f 'l)))
My new function fully works the way I expect it to when calling it with an unevaluated list, but not when I pass it an unevaluated list.
The job of deep-substitute is to fill in a template form and return it. The problem gets harder if you try to make deep-substitute also responsible for doing the next step in the transformations as well. Perhaps let it return the value, then pass that value on to another transform function after it's returned.
Here's an annotated working example:
user> (defn deep-substitute [m l]
(map (fn [i]
(if (seq? i) ;; if this is a sequence,
(deep-substitute m i) ;; finish the sequence and include the result here
(get m i i))) ;; otherwise get the new value from the map, if found
l)) ;; if it's not found, us the value unchanged.
#'user/deep-substitute
then test it on your example:
user> (deep-substitute '{x false, y true} '(or false x y))
(or false false true)
and a more nested example:
user> (deep-substitute '{x false, y true} '(or false (and x (or y x)) y))
(or false (and false (or true false)) true)
a common next step is to wrap that in a macro so it can modify forms before they are evaluated, then evaluate that newly created from to find out what value it becomes:
user> (defmacro dsub [m l]
(deep-substitute m l))
#'user/dsub
and test it
user> (dsub {x false, y true} (or false (and x (or y x)) y))
true
user> (dsub {x false, y true} (or false x))
false
or pass the resulting form (unevaluated) into another function by nesting it:
user> (defn f [expression]
(reverse expression))
#'user/f
user> (f (deep-substitute '{x false, y true} '(or false (and x (or y x)) y)))
(true (and false (or true false)) false or)
A common pattern is to use the threading macros -> ->> etc. to pass the result from transform to transform until the final result is made by composing many simple operations:
user> (->> '(or false (and x (or y x)) y)
(deep-substitute '{x false, y true})
f
(deep-substitute '{false, 41 true 42}))
(42 (and 41 (or 42 41)) 41 or)
first try with the basic approach of the passing list as an argument to the function. You can refer below example
(defn passlist [a]
(println a))
(passlist '(1 2 3))
Output will:
#'user/passlist
(1 2 3)

Clojure : function returns nil rather an evaluated expression

I have written a function that sums the members of a list. Pretty straightforward, newbie stuff, but for some reason it returns nil, and I am at a loss as to why: this should be a no-brainer. The implementation and function call follow.
The implementation:
(defn add-list-members
([x] (add-list-members x 0))
([x total]
(if (= (count x) 2)
(+ (first x) (first (rest x)) total))
(if (= (count x) 1)
(+ (first x) total))
(if (> (count x) 2)
(recur (rest (rest x)) (+ (+ (first x) (first (rest x))) total)))))
The call to the function:
(println "our total is: " (add-list-members '(2 23 33 14 33 134 9000 98993)))
Meanwhile, I have a debugging version with print statements added, and I have been able to verify that the implementation works as it should.
Debugging version:
(defn add-list-members-debug
([x] (add-list-members-debug x 0))
([x total]
(println ">>> our list now: " x)
(println ">>> our total now: " total)
(if (= (count x) 2)
(println "outcome 2 : " (+ (first x) (first (rest x)) total)))
(if (= (count x) 1)
(println "outcome 1 : " (+ (first x) total)))
(if (> (count x) 2)
(recur (rest (rest x)) (+ (+ (first x) (first (rest x))) total)))))
Call to debugging version:
(add-list-members-debug '(2 23 33 14 33 134 9000 98993))
The development tools I am using are Vim plugged into the Leiningen REPL. Any hints about what I'm doing wrong here would be most appreciated.
You used if in a wrong way. Consider the following code: I intentionally simplified the code to make it clear what happens.
(defn xxx [v]
(if (= (count v) 1) "one")
(if (= (count v) 2) "two")
(if (> (count v) 2) "more"))
What happens if you run (xxx [1])? Perhaps you expect the code will return "one", however, it returns nil. Why?
Function returns value of its last expression, in this case, the last line (if (> (count v) 2) "more"). If you pass [1], the first if expression returns "one", which is ignored. The second if will return nil, which is also ignored. The third and the last will return nil, which is the return value of the function.
Perhaps the simplest way to compute sum of elements is:
(defn add-elements [xs] (apply + xs))
or
(defn add-elements [xs] (reduce + xs))
Your code can be reimplemented in much simpler way:
(defn add-elements
([xs] (add-elements xs 0))
([xs total] (if (empty? xs) total
(recur (rest xs) (+ total (first xs))))))
The parentheses are wrong, or at least suboptimal, and you have no base case that returns total. (About the parentheses: Your indentation, which is correct given the parentheses, shows this: Each if is on the same level; none of them are in the "else" position.) Here's one correct version:
(defn add-list-members
([x] (add-list-members x 0))
([x total]
(if (= (count x) 0)
total
(if (= (count x) 2)
(+ (first x) (first (rest x)) total)
(if (= (count x) 1)
(+ (first x) total)
(if (> (count x) 2)
(recur (rest (rest x)) (+ (+ (first x) (first (rest x))) total))))))))
You get nil as the return value because when the last if test fails, it goes to the else clause, which in this case is an empty end of a list, i.e. nil.
However, the multiple ifs can be replaced with one cond. You can also use ffirst for (first (first, fnext instead of (first (rest, and nnext instead of (rest (rest. It would also be more idiomatic to use a predicate such as empty? instead of checking for count equal to 0; I used count for the base case simply to maintain the parallel with your existing code. The simplest version might be:
(defn add-list-members [x] (apply + x))
You could also use reduce for a very simple version. You may just have wanted to experiment with recur, though.
(Well, you could do it without using the embedded else clauses, as in your original, but I wouldn't recomment it, and you still need the empty sequence base case. When you put multiple separate expressions in an function definition, each one of them always gets executed. This is inefficient and, I feel, error prone. Using multiple, separate expressions in a function definition makes sense when you're creating side effects--e.g. adding print statements for debugging.)

How to execute "do" on elements in a sequence in clojure

I've been trying to figure out how to execute expressions that are stored as elements in a sequence. For example, here are two expressions in a sequence:
user=> (def z '((println 'x) 'y))
#'user/z
user=> z
((println (quote x)) (quote y))
Trying to use do or doall on them doesn’t seem to do anything
user=> (do z)
((println (quote x)) (quote y))
user=> (doall z)
((println (quote x)) (quote y))
The output I am trying to get is if I were to execute them not as a sequence but as a list of arguments
user=> (do (println (quote x)) (quote y))
x
y
I tried mapping eval but that gives me an extra nil and returns a list
user=> (map eval z)
(x
nil y)
Any help would be greatly appreciated!
Do is a macro that evaluates its args, and returns the last one. let, fn, for among others contain implicit do bodies.
In your map example, the "extra nil" is the return value of the println, and it is actually the x that is extra (it is the printed output interleaved with the sequence that map returns).
Your definition of z does not create executable objects, but lists. Lists just evaluate to themselves when used.
Do you need to evaluate expressions stored as literals?
It is easy to wrap each each one as a thunk (a function of no arguments).
user> (def z [#(println 'x) #(do 'y)])
#'user/z
We can use reduce to execute them all, and only return the last one.
user> (reduce (fn [_ e] (e)) nil z)
x
y
here x is printed, and y is returned.
If you really need to use a list with eval, you can substitute it as apropriate above ((e) becomes (eval e) and z gets your original definition).
(def z '((println 'x) 'y))
Your z definition has a quote saying DON'T EVALUATE ME. So z is defined as an unevaluated expression. You want to evaluate unevaluated code so naturally you'll want to use eval; however (eval z) won't work because (println x) will print x but return the value nil. (nil y) will not work and isn't what you want.
What you do want is do; do only returns the value of the last expression so used here nil does not get in the way and you execute all your expressions. You want your end result to be:
(do (println 'x)
'y))
Let's transform z to look like that.
(cons 'do z)
=> (do (println (quote x)) (quote y))
Looking familiar? eval it!
(eval (cons 'do z))
=> x
y
You're looking to eval code here.
user=> (def z '(do (println "hey!" 'x) 'y))
#'user/z
user=> (eval z)
hey! x
y
Note that I added the do so that both expressions would be evaluated. The code in the question contained an error.
((println 'x) 'y)
First thing that would occur would be to print 'x and println returns nil, so the expression would then look like this.
(nil 'y)
nil is not a function, but it's being evaluated at the head of the list, so that's an error. Or a null pointer exception in this case.
user=> (def z '((println 'x) 'y))
#'user/z
user=> (eval z)
x
NullPointerException user/eval674 (NO_SOURCE_FILE:1)