Coming from Functional Java and a little Scala, I am now learning Clojure step by step. At the moment, given that I have free time, I am reading and doing exercises from "Structure and Interpretation of Computer Programs".
I am stuck at the following exercise, where I know how to solve the problem, which is by completely removing let
and put (take 2 ...
directly in map
.
; Exercise 1.3
;; Define a procedure that takes three numbers as arguments
;; and returns the sum of the squares of the two larger numbers.
(defn square-sum-largest-pair [a b c]
"Sums the square of the largest two number of the three in input.
Maybe a little overkill to use a list here, but it's just for fun."
(let [[two-items] (take 2 (reverse (sort [a b c])))]
(reduce + (map (fn [x] (m/expt x 2)) two-items))))
The following error is displayed when I execute square-sum-largest-pair
:
actual: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long
at clojure.lang.RT.seqFrom (RT.java:505)
clojure.lang.RT.seq (RT.java:486)
clojure.core$seq.invoke (core.clj:133)
clojure.core$map$fn__4245.invoke (core.clj:2551)
Why is this happening?
The problem is the []
round two-items
. This binds two-items
to the first of the sequence (take 2 (reverse (sort [a b c])))
, ignoring the rest. Trying to use this - the maximum number - as a sequence in the subsequent map
produces the observed error.
Removing the []
(and squaring with *
for simplicity), we get
(defn square-sum-largest-pair [a b c]
(let [two-items (take 2 (reverse (sort [a b c])))]
(reduce + (map (fn [x] (* x x)) two-items))))
(square-sum-largest-pair 1 2 3)
13