I'm new to Clojure, and can't find an equivalent of integer? in Chez scheme 8.4, mainly for test cases as below:
(integer? 39.0)
=> #t
The function I've come up so far is:
(defn actual-integer? [x] (or (= 0.0 (- x (int x))) (integer? x)))
Does it work when x is arbitrary number types or is there a better solution?
Thanks.
Well, strictly speaking 39.0 isn't an integer literal because it has the .0 part at the end. A simple implementation of the procedure would be:
(defn actual-integer? [x] (== (int x) x))
Notice that the == operator:
Returns non-nil if nums all have the equivalent value (type-independent), otherwise false
Related
I'm using the function iterate to create a lazy sequence. The sequence keeps producing new values on each item. At one point however the produced values "doesn't make sense" anymore, so they are useless. This should be the end of the lazy sequence. This is the intended behavior in a abstract form.
My approach was to let the sequence produce the values. And once detected that they are not useful anymore, the sequence would only emit nil values. Then, the sequence would be wrapped with a take-while, to make it finite.
simplified:
(take-while (comp not nil?)
(iterate #(let [v (myfunction1 %)]
(if (mypred? (myfunction2 v)) v nil)) start-value))
This works, but two questions arise here:
Is it generally a good idea to model a finite lazy sequence with a nil as a "stopper", or are there better ways?
The second question would be related to the way I implemented the mechanism above, especially inside the iterate.
The problem is: I need one function to get a value, then a predicate to test if it's valid, if yes: in needs to pass a second function, otherwise: return nil.
I'm looking for a less imperative way tho achieve this, more concretely omitting the let statement. Rather something like this:
(defn pass-if-true [pred v f]
(when (pred? v) (f v)))
#(pass-if-true mypred? (myfunction1 %) myfunction2)
For now, I'll go with this:
(comp #(when (mypred? %) (myfunction2 %)) myfunction1)
Is it generally a good idea to model a finite lazy sequence with a nil as a "stopper", or are there better ways?
nil is the idiomatic way to end a finite lazy sequence.
Regarding the second question, try writing it this way:
(def predicate (partial > 10))
(take-while predicate (iterate inc 0))
;; => (0 1 2 3 4 5 6 7 8 9)
Here inc takes the previous value and produces a next value, predicate tests whether or not a value is good. The first time predicate returns false, sequence is terminated.
Using a return value of nil can make a lazy sequence terminate.
For example, this code calculates the greatest common divisor of two integers:
(defn remainder-sequence [n d]
(let [[q r] ((juxt quot rem) n d)]
(if (= r 0) nil
(lazy-seq (cons r (remainder-sequence d r))))))
(defn gcd [n d]
(cond (< (Math/abs n) (Math/abs d)) (gcd d n)
(= 0 (rem n d)) d
:default (last (remainder-sequence n d))))
(gcd 100 32) ; returns 4
(defn prime [x]
(if (#(<= % (Math/sqrt x)) (first (filter zero? (mod x (range 2 (inc x))))))
false
true))
Hi there! I want to check the given number is prime or not using clojure. Firstly, I want to filter all the divisors of x, then select the first number of these divisors. Finally, comparing to the square root of x, if the first divisor is smaller or equal to x, then the given number is not a prime. Otherwise, it is. However, when I run the code, I got such an error. How can I figure out the problem that convert a Lazyseq to a Number? I would appreciate if anyone can help me!
I think the problem is slightly different. We do not want to try values greater than the square root of the number we want to know is prime or not. Reason is explain in this SO. (Basically if x = a * b, then both a AND b cannot be greater than the square root)
So the sequence we are building, is up to the square root
(defn root-1 [x]
(inc (long (Math/sqrt x))))
(defn range-1 [x]
(range 2 (root-1 x)))
Finally, we are filtering on divisor:
(defn filter-1 [x]
(filter #(zero? (rem x %))
(range-1 x)))
And especially, we can stop at the first one, and filter being lazy, that comes up nicely with:
(defn is-prime [x]
(nil? (first (filter-1 x))))
Which we can try with:
(is-prime 10) ; false
(is-prime 11) ; true
Fast check that number is prime:
(ns example.core
(:gen-class)
(:require [clojure.core.reducers :as r]))
(defn prime-number?
[n]
(let [square-root (Math/sqrt n)
mod-zero? (fn [res new-val]
(if (zero? (mod n new-val))
(reduced false)
true))]
(r/reduce mod-zero? true (range 2 (inc square-root)))))
(prime-number? 2147483647)
;=> true
Two comments:
range returns a seq, which you are trying to apply (mod x ...) to. I think you are missing a map..
There is no real point in returning true and false from an if, if you think about it ;) (hint, try to see how the function not behaves)
You should make another attempt and update us on what you came up with!
Paraphrasing your recipe:
Filter all the divisors of x.
Select the first of these.
If it is smaller then or equal to the square root of x, then x
is not a prime.
The given code has the problems:
The surrounding if form is redundant.
The filter function is wrong. It ought to incorporate the zero? and
the mod x.
There is no need to construct and apply an anonymous function. Just
apply the test directly.
And, though the repaired algorithm would work, it is still clumsy.
The first divisor of a prime x is x itself. There is no need to
muck about with square roots.
The range ought to be from 2 to the square root of x. Then a nil
value for the first divisor indicates a prime.
How can the absolute number of a value be calculated in Clojure?
(abs 1) => 1
(abs -1) => 1
(abs 0) => 0
As of Clojure 1.11, it is simply (abs -1) in both Clojure and Clojurescript.
In versions before, for double, float, long and int you can use the java.lang.Math method abs (Math/abs -1)
Take care it won't work for decimals, ratio's, bigint(eger)s and other Clojure numeric types. The official clojure contrib math library that tries guarantee working correctly with all of these is clojure.math.numeric-tower
you could always do
(defn abs [n] (max n (- n)))
The deprecated clojure.contrib.math provides an abs function.
The source is:
(defn abs "(abs n) is the absolute value of n" [n]
(cond
(not (number? n)) (throw (IllegalArgumentException.
"abs requires a number"))
(neg? n) (- n)
:else n))
As #NielsK points out in the comments, clojure.math.numeric-tower is the successor project.
abs is now available in the core clojure library since Clojure 1.11 release.
Docs for abs https://clojure.github.io/clojure/branch-master/clojure.core-api.html#clojure.core/abs
Usage: (abs a)
Returns the absolute value of a.
If a is Long/MIN_VALUE => Long/MIN_VALUE
If a is a double and zero => +0.0
If a is a double and ##Inf or ##-Inf => ##Inf
If a is a double and ##NaN => ##NaN
Added in Clojure version 1.11
I'm trying to learn functional programming with SICP. I want to use Clojure.
Clojure is a dialect of Lisp but I'm very unfamiliar with Lisp. This code snippet unclean and unreadable. How to write more efficient code with Lisp dialects ?
And how to pass multiple parameters function from other function ?
(defn greater [x y z]
(if (and (>= x y) (>= x z))
(if (>= y z)
[x,y]
[x,z])
(if (and (>= y x) (>= y z))
(if (>= x z)
[y,x]
[y,z])
(if (and (>= z x) (>= z y))
(if (>= y x)
[z,y]
[z,x])))))
(defn sum-of-squares [x y]
(+ (* x x) (* y y)))
(defn -main
[& args]
(def greats (greater 2 3 4))
(def sum (sum-of-squares greats)))
You are asking two questions, and I will try to answer them in reverse order.
Applying Collections as Arguments
To use a collection as an function argument, where each item is a positional argument to the function, you would use the apply function.
(apply sum-of-squares greats) ;; => 25
Readability
As for the more general question of readability:
You can gain readability by generalizing the problem. From your code sample, it looks like the problem consists of performing the sum, of the squares, on the two largest numbers in a collection. So, it would be visually cleaner to sort the collection in descending order and take the first two items.
(defn greater [& numbers]
(take 2 (sort > numbers)))
(defn sum-of-squares [x y]
(+ (* x x) (* y y)))
You can then use apply to pass them to your sum-of-squares function.
(apply sum-of-squares (greater 2 3 4)) ;; => 25
Keep in Mind: The sort function is not lazy. So, it will both realize and sort the entire collection you give it. This could have performance implications in some scenarios. But, in this case, it is not an issue.
One Step Further
You can further generalize your sum-of-squares function to handle multiple arguments by switching the two arguments, x and y, to a collection.
(defn sum-of-squares [& xs]
(reduce + (map #(* % %) xs)))
The above function creates an anonymous function, using the #() short hand syntax, to square a number. That function is then lazily mapped, using map, over every item in the xs collection. So, [1 2 3] would become (1 4 9). The reduce function takes each item and applies the + function to it and the current total, thus producing the sum of the collection. (Because + takes multiple parameters, in this case you could also use apply.)
If put it all together using one of the threading macros, ->>, it starts looking very approachable. (Although, an argument could be made that, in this case, I have traded some composability for more readability.)
(defn super-sum-of-squares [n numbers]
(->> (sort > numbers)
(take n)
(map #(* % %))
(reduce +)))
(super-sum-of-squares 2 [2 3 4]) ;;=> 25
(defn greater [& args] (take 2 (sort > args)))
(defn -main
[& args]
(let [greats (greater 2 3 4)
sum (apply sum-of-squares greats)]
sum))
A key to good clojure style is to use the built in sequence operations. An alternate approach would have been a single cond form instead of the deeply nested if statements.
def should not be used inside function bodies.
A function should return a usable result (the value returned by -main will be printed if you run the project).
apply uses a list as the args for the function provided.
To write readable code, use the functions provided by the language as much as possible:
e.g. greater can be defined as
(defn greater [& args]
(butlast (sort > args)))
To make sum-of-squares work on the return value from greater, use argument destructuring
(defn sum-of-squares [[x y]]
(+ (* x x) (* y y)))
which requires the number of elements in the argument sequence to be known,
or define sum-of-squares to take a single sequence as argument
(defn sum-of-squares [args]
(reduce + (map (fn [x] (* x x)) args)))
Coming from imperative programming languages, I am trying to wrap my head around Clojure in hopes of using it for its multi-threading capability.
One of the problems from 4Clojure is to write a function that generates a list of Fibonacci numbers of length N, for N > 1. I wrote a function, but given my limited background, I would like some input on whether or not this is the best Clojure way of doing things. The code is as follows:
(fn fib [x] (cond
(= x 2) '(1 1)
:else (reverse (conj (reverse (fib (dec x))) (+ (last (fib (dec x))) (-> (fib (dec x)) reverse rest first))))
))
The most idiomatic "functional" way would probably be to create an infinite lazy sequence of fibonacci numbers and then extract the first n values, i.e.:
(take n some-infinite-fibonacci-sequence)
The following link has some very interesting ways of generating fibonnaci sequences along those lines:
http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci
Finally here is another fun implementation to consider:
(defn fib [n]
(let [next-fib-pair (fn [[a b]] [b (+ a b)])
fib-pairs (iterate next-fib-pair [1 1])
all-fibs (map first fib-pairs)]
(take n all-fibs)))
(fib 6)
=> (1 1 2 3 5 8)
It's not as concise as it could be, but demonstrates quite nicely the use of Clojure's destructuring, lazy sequences and higher order functions to solve the problem.
Here is a version of Fibonacci that I like very much (I took the implementation from the clojure wikibook: http://en.wikibooks.org/wiki/Clojure_Programming)
(def fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
It works like this: Imagine you already have the infinite sequence of Fibonacci numbers. If you take the tail of the sequence and add it element-wise to the original sequence you get the (tail of the tail of the) Fibonacci sequence
0 1 1 2 3 5 8 ...
1 1 2 3 5 8 ...
-----------------
1 2 3 5 8 13 ...
thus you can use this to calculate the sequence. You need two initial elements [0 1] (or [1 1] depending on where you start the sequence) and then you just map over the two sequences adding the elements. Note that you need lazy sequences here.
I think this is the most elegant and (at least for me) mind stretching implementation.
Edit: The fib function is
(defn fib [n] (nth fib-seq n))
Here's one way of doing it that gives you a bit of exposure to lazy sequences, although it's certainly not really an optimal way of computing the Fibonacci sequence.
Given the definition of the Fibonacci sequence, we can see that it's built up by repeatedly applying the same rule to the base case of '(1 1). The Clojure function iterate sounds like it would be good for this:
user> (doc iterate)
-------------------------
clojure.core/iterate
([f x])
Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects
So for our function we'd want something that takes the values we've computed so far, sums the two most recent, and returns a list of the new value and all the old values.
(fn [[x y & _ :as all]] (cons (+ x y) all))
The argument list here just means that x and y will be bound to the first two values from the list passed as the function's argument, a list containing all arguments after the first two will be bound to _, and the original list passed as an argument to the function can be referred to via all.
Now, iterate will return an infinite sequence of intermediate values, so for our case we'll want to wrap it in something that'll just return the value we're interested in; lazy evaluation will stop the entire infinite sequence being evaluated.
(defn fib [n]
(nth (iterate (fn [[x y & _ :as all]] (cons (+ x y) all)) '(1 1)) (- n 2)))
Note also that this returns the result in the opposite order to your implementation; it's a simple matter to fix this with reverse of course.
Edit: or indeed, as amalloy says, by using vectors:
(defn fib [n]
(nth (iterate (fn [all]
(conj all (->> all (take-last 2) (apply +)))) [1 1])
(- n 2)))
See Christophe Grand's Fibonacci solution in Programming Clojure by Stu Halloway. It is the most elegant solution I have seen.
(defn fibo [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))
(take 10 (fibo))
Also see
How can I generate the Fibonacci sequence using Clojure?