# 4clojure Double Down question

This pertains to question #15 on 4clojure “Double Down.” Original problem link here: https://www.4clojure.com/problem/15

## My goal

My goal is to evaluate: “Do all the statements evaluate to true?” If yes, return true, else return false. In short, I want to write a single expression that will run all the test cases at once.

Ps. I have written this question post backwards on purpose because I think question 3 is the best question, but for those who want to see my thought process in more detail, they can work their way to 3 from 1 or 2. Sorry and thank you

## 3. Last question update:

Is it possible to tweak “example B” so that it works as desired? If so, how?

## 2. Updated question:

For what cases is `every? true?` appropriate, and what cases is `every-pred true?` appropriate? I have a hunch that, semantically speaking, `every?` takes one predicate to evaluate over a collection of values (ie. non-predicates), whereas, `every-pred true?` takes many predicates and simply asks. I think my brain has been scrambled…

## 1. Initial question:

Why does this work as expected…

``````;; example A
(and (= (#(* % 2) 2) 4)
(= (#(* % 2) 3) 6)
(= (#(* % 2) 11) 22)
(= (#(* % 2) 7) 14))
;; => true
``````

… whereas the following simply returns an error:

``````;; example B
(every? true?
((= (#(* % 2) 2) 4)
(= (#(* % 2) 3) 6)
(= (#(* % 2) 11) 22)
(= (#(* % 2) 7) 14)))
;; => class java.lang.Boolean cannot be cast to class clojure.lang.IFn
``````

… Upon some further reflection and research, I found this:

``````;; example C
((every-pred true?)
(= (#(* % 2) 2) 4)
(= (#(* % 2) 3) 6)
(= (#(* % 2) 11) 22)
(= (#(* % 2) 7) 14))
;; => true
``````

… which appears to work as desired

In short, I’d like to understand why “example B” gives an error, and if there was a better (clearer or simpler) way to solve for my personal challenge than examples A and C.

It looks like you got tripped up by evaluation semantics and order.
In case 2, read the error message:

``````;; => class java.lang.Boolean cannot be cast to class clojure.lang.IFn
``````

The compiler thinks you’re trying to use a boolean as a function. Are you?
Let’s evaluate the expression step by step as Clojure would:

``````(every?
true?
((= (#(* % 2) 2) 4)
(= (#(* % 2) 3) 6)
(= (#(* % 2) 11) 22)
(= (#(* % 2) 7) 14)))
;;;
(every?
true?
((= (f 2) 4)
(= (f 3) 6)
(= (f 11) 22)
(= (f 7) 14)))
;;;
(every?
true?
((= 4 4)
(= 6 6)
(= 22 22)
(= 14 14)))
;;;
(every?
true?
(true true true true))
``````

This is where you get a run time exception, you have a boolean in a call position and the emitted code is trying to call it as a function. No good.
Literal lists = evaluation.
The solution is to use literal vectors:

``````(every?
true?
[(= (#(* % 2) 2) 4)
(= (#(* % 2) 3) 6)
(= (#(* % 2) 11) 22)
(= (#(* % 2) 7) 14)])
``````

This does what you expect.
It is best to use `and` here because it does not evaluate its arguments eagerly (it’s a macro, not a function).
`every-pred` works almost by accident, it returns a function which you then call on a bunch of values which are true. The function is true if all the combinations of the provided predicates and values are true. The only predicate is `true?` and all the values are `true`, so it works.
There are a few other solutions you can find if you use a vector.

2 Likes