Is there a smart way to validate function input in Clojure? - clojure

I'm writing a simple DiceRoller application and I've created the primary function, however I'm wondering if there is a "smart" way to validate function inputs in Clojure rather than using branching conditionals to validate input? My function is below with a sample test, I would have to also test if n is not a number with another if or an or and it feels messy.
Also if anyone can point out a smarter way to do this function I would appreciate any feedback, this is my first attempt at trying to program functionally
(ns DiceRoller)
(defn roll
"rolls a specified number of n sided dice "
([] (roll 1 6))
([number] (roll number 6))
([number n]
(if-not number? number (throw (IllegalArgumentException. (str "incorrect input, integers only"))))
(take number (repeatedly #(+ (rand-int n) 1)))
)
)

Sure there is - you can use a :pre assertion for that.
(defn some-fun [x]
{:pre [(number? x)]}
(foo x))
Now you'll get AssertionError Assert failed: (number? x) if you pass the function a non-numeric argument x.
Checking whether the input is a number is kind of useless as #amalloy already pointed out, but there are lots of totally valid precondition (and postcondition for that matter) checks that you might want to apply to your function. You can see some more details on the subject here and here.

Mostly the Clojure attitude is "just assume you got the right thing". In this case, if you took out your check entirely, the user would get basically the same exception eventually. But if you really wanted to do this, you should do it correctly! Right now your code throws an exception on every input, because you're missing parens around (number? number).

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

conj not updating vector inside of loop

I'm trying to teach myself clojure. This is just supposed to be a simple function that takes a value and adds each of its preceding values together and returns the sum of those values.
The problem is that while in the loop function, numbers isn't modified with conj like I would expect it to be - numbers just stays an empty vector. Why is that?
(defn sum
[number]
(do (def numbers (vector))
(loop [iteration number]
(if (> iteration 0)
(conj numbers iteration)
(recur (dec iteration))))
(map + numbers)))
A few hints (not an answer):
Don't use do.
Use let, not def, inside a function.
Use the result returned by conj, or it does nothing.
Pass the result back through the recur.
Besides, your sum function ignores its number argument.
I think you're getting confused between number (the number of things you want to add) and numbers (the things themselves). Remember,
vectors (and other data structures) know how long they are; and
they are often, as in what follows, quickly and concisely dealt with as
sequences, using first and rest instead of indexing.
The code pattern you are searching for is so common that it's been captured in a standard higher order function called reduce. You can get the effect you want by ...
(defn sum [coll] (reduce + coll))
or
(def sum (partial reduce +))
For example,
(sum (range 10))
;45
Somewhat off-topic:
If I were you, and I once was, I'd go through some of the fine clojure tutorials available on the web, with a REPL to hand. You could start looking here or here. Enjoy!
Your function does not work fro three main reasons :
you assumed that conj will update the value of variable numbers (but in fact it returns a copy of it bound to another name)
you used loop/recur pattern like in classical imperative style (it does not work the same)
Bad use of map
Thumbnail gave the idiomatic answer but here are correct use of your pattern :
(defn sum
[number]
(loop [iteration number
numbers []]
(if (<= iteration 0)
(reduce + numbers)
(recur (dec iteration) (conj numbers iteration)))))
The loop/recur pattern executes its body with updated values passed by recur.
Recur updates values listed after the loop. Here, while iteration is strictly positive, recur is executed. However, when iteration reaches 0, (reduce + numbers) (actual sum) is executed on the result of multiple recursions and so the recursion ends.

how to spec a lazy-seq generating function?

I wish to use spec in my pre and post conditions of a generator function. A simplified example of what I wish to do is described below:
(defn positive-numbers
([]
{:post [(s/valid? (s/+ int?) %)]}
(positive-numbers 1))
([n]
{:post [(s/valid? (s/+ int?) %)]}
(lazy-seq (cons n (positive-numbers (inc n))))))
(->> (positive-numbers) (take 5))
However, defining the generator function like that seems to cause stack-overflow, the cause being that spec will eagerly try to evaluate the whole thing, -or something like that....
Is there another way of using spec to describe the :post result of a generator function like the one above (without causing stack-overflow)?
The theoretically correct answer is that in general you cannot check whether a lazy sequence matches a spec without realizing all of it.
In the case of your specific example of (s/+ int?), given a lazy sequence, how would one establish merely by observing the sequence whether all its elements are integers? However many elements you examine, the next one could always be a keyword.
This is the sort of thing that a type system like, say, core.typed may be able to prove, but a runtime-predicate-based assertion won't be able to check.
Now, in addition to s/+ and s/*, spec (as of Clojure 1.9.0-alpha14) also has a a combinator called s/every, whose docstring says this:
Note that 'every' does not do exhaustive checking, rather it samples *coll-check-limit* elements.
So we have e.g.
(s/valid? (s/* int?) (concat (range 1000) [:foo]))
;= false
but
(s/valid? (s/every int?) (concat (range 1000) [:foo]))
;= true
(with the default *coll-check-limit* value of 101).
This actually isn't an immediate fix to your example – plugging in s/every in place of s/+ won't work, because each recursive call will want to validate its own return value, which will involve realizing more of the sequence, which will involve more recursive calls etc. But you could factor out the sequence-building logic to a helper function with no postconditions and then have positive-numbers declare the postcondition and call that helper function:
(defn positive-numbers* [n]
(lazy-seq (cons n (positive-numbers* (inc n)))))
(defn positive-numbers [n]
{:post [(s/valid? (s/every int? :min-count 1) %)]}
(positive-numbers* n))
Note the caveats:
this will still realize a good chunk of your sequence, which may wreak havoc with your application's performance profile;
the only watertight guarantee here is that the prefix actually examined is as desired, if the seq has a weird item at position 123456, that will go unnoticed.
Because of (1), this is something that makes more sense as a test-only assertion. (2) may be acceptable – you'll still catch some silly typos and the documentation value of the spec is there anyway; if it isn't and you do want an absolutely watertight guarantee that your return type is as desired, then again, core.typed (perhaps used locally just for a handful of namespaces) may be the better bet.

What are side-effects in predicates and why are they bad?

I'm wondering what is considered to be a side-effect in predicates for fns like remove or filter. There seems to be a range of possibilities. Clearly, if the predicate writes to a file, this is a side-effect. But consider a situation like this:
(def *big-var-that-might-be-garbage-collected* ...)
(let [my-ref *big-var-that-might-be-garbage-collected*]
(defn my-pred
[x]
(some-operation-on my-ref x)))
Even if some-operation-on is merely a query that does not change state, the fact that my-pred retains a reference to *big... changes the state of the system in that the big var cannot be garbage collected. Is this also considered to be side-effect?
In my case, I'd like to write to a logging system in a predicate. Is this a side effect?
And why are side-effects in predicates discouraged exactly? Is it because filter and remove and their friends work lazily so that you cannot determine when the predicates are called (and - hence - when the side-effects happen)?
GC is not typically considered when evaluating if a function is pure or not, although many actions that make a function impure can have a GC effect.
Logging is a side effect, as is changing any state in the program or the world. A pure function takes data and returns data, without modifying anything else.
https://softwareengineering.stackexchange.com/questions/15269/why-are-side-effects-considered-evil-in-functional-programming covers why side effects are avoided in functional languages.
I found this link helpful
The problem is determining when, or even whether, the side-effects will occur on any given call to the function.
If you only care that the same inputs return the same answer, you are fine. Side-effects are dependent on how the function is executed.
For example,
(first (filter odd? (range 20)))
; 1
But if we arrange for odd? to print its argument as it goes:
(first (filter #(do (print %) (odd? %)) (range 20)))
It will print 012345678910111213141516171819 before returning 1!
The reason is that filter, where it can, deals with its sequence argument in chunks of 32 elements.
If we take the limit off the range:
(first (filter #(do (print %) (odd? %)) (range)))
... we get a full-size chunk printed: 012345678910111213141516171819012345678910111213141516171819202122232425262728293031
Just printing the argument is confusing. If the side effects are significant, things could go seriously awry.

Idiomatic no-op/"pass"

What's the (most) idiomatic Clojure representation of no-op? I.e.,
(def r (ref {}))
...
(let [der #r]
(match [(:a der) (:b der)]
[nil nil] (do (fill-in-a) (fill-in-b))
[_ nil] (fill-in-b)
[nil _] (fill-in-a)
[_ _] ????))
Python has pass. What should I be using in Clojure?
ETA: I ask mostly because I've run into places (cond, e.g.) where not supplying anything causes an error. I realize that "most" of the time, an equivalent of pass isn't needed, but when it is, I'd like to know what's the most Clojuric.
I see the keyword :default used in cases like this fairly commonly.
It has the nice property of being recognizable in the output and or logs. This way when you see a log line like: "process completed :default" it's obvious that nothing actually ran. This takes advantage of the fact that keywords are truthy in Clojure so the default will be counted as a success.
There are no "statements" in Clojure, but there are an infinite number of ways to "do nothing". An empty do block (do), literally indicates that one is "doing nothing" and evaluates to nil. Also, I agree with the comment that the question itself indicates that you are not using Clojure in an idiomatic way, regardless of this specific stylistic question.
The most analogous thing that I can think of in Clojure to a "statement that does nothing" from imperative programming would be a function that does nothing. There are a couple of built-ins that can help you here: identity is a single-arg function that simply returns its argument, and constantly is a higher-order function that accepts a value, and returns a function that will accept any number of arguments and return that value. Both are useful as placeholders in situations where you need to pass a function but don't want that function to actually do much of anything. A simple example:
(defn twizzle [x]
(let [f (cond (even? x) (partial * 4)
(= 0 (rem x 3)) (partial + 2)
:else identity)]
(f (inc x))))
Rewriting this function to "do nothing" in the default case, while possible, would require an awkward rewrite without the use of identity.