i'm trying to write a simple Clojure program to find the maximum element of a list. This is the code I wrote so far:
(ns iotest.core
(:gen-class))
(defn getLargest [L]
"Get the largest element of a given list L"
(cond
(empty? L) nil
(empty? (rest L)) (first L)
((> (first L) (getLargest (rest L)))) (first L)
:else (getLargest (rest L))))
(defn -main []
(let
[L (4 5 10 1)
largest (getLargest L)]
(println "Largest element of" L "is" largest)))
The problem is, I get the following error(i'm using leiningen):
class java.lang.Long cannot be cast to class clojure.lang.IFn (java.lang.Long is in module java.base of loader 'bootstrap';
clojure.lang.IFn is in unnamed module of loader 'app')
What I'm doing wrong?
I know about the max
function, but I want to implement it by myself for learning purposes.
This part:
(let [L (4 5 10 1) ... )
is missing quote
- or you can use vector instead:
(4 5 10 1)
error
'(4 5 10 1)
=> (4 5 10 1)
[4 5 10 1]
=> [4 5 10 1]
There is also error with ((> (first L) (getLargest (rest L)))) (first L)
(class java.lang.Boolean cannot be cast to class clojure.lang.IFn, you have additional pair of parentheses here) and style error with getLargest
- Clojure uses kebab-case, so correct name is get-largest
.
For correct result check reduce
. Min
and max
don't work for empty lists, so you have to be careful about that:
(defn get-largest [lst]
(if (empty? lst)
:none
(reduce (fn [acc element]
(if (> element acc) element acc))
(first lst)
(rest lst))))
(let [lst [4 5 10 1]
largest (get-largest lst)]
(println "Largest element of" lst "is" largest))
Largest element of [4 5 10 1] is 10
=> nil
(let [lst []
largest (get-largest lst)]
(println "Largest element of" lst "is" largest))
Largest element of [] is :none
=> nil
EDIT: This is a little bit better:
(defn get-largest [lst]
(when (seq lst)
(reduce #(if (> %2 %1) %2 %1)
(first lst)
(rest lst))))
(let [lst [4 5 10 1]]
(if-let [largest (get-largest lst)]
(println "Largest element of" lst "is" largest)
(println "Sequence is empty")))
Largest element of [4 5 10 1] is 10
=> nil