On Jul 9, 2014, at 8:48 PM, Stephen Feyrer <[email protected]> wrote:
> Hi,
>
> I tried to create the function below in a Lighttable instarepl. In lieu of
> any better idea for formatting, the < > statements below indicate instarepl
> output.
>
> (defn avged ([x]
> ((def sumed (reduce + x)) < 10 >
> (def counted (count x)) < 4 >
> (def result (/ sumed counted)) < 5/2 >
> result
> )))
>
> (avged [1 2 3 4]) < java.lang.ClassCastException: java.lang.Long cannot be
> cast to clojure.lang.IFn
> Var.java:392 clojure.lang.Var.fn
> Var.java:423 clojure.lang.Var.invoke
> (Unknown Source) user/avged >
>
> The objective of this function is just a learning exercise.
>
> I have three questions:
>
> 1. Why doesn't it work, return a value?
Hi Stephen,
The main reason it doesn't work is that the expression after the parameter list
[x] is a list and will be interpreted as a function call, with the function
being whatever is returned from the first thing in the list -- which in this
case is the "def sumed" definition, which returns the defined var.
You could patch (not recommended!) this by adding "do" to the beginning of that
list:
(defn avged
([x]
(do
(def sumed (reduce + x))
(def counted (count x))
(def result (/ sumed counted))
result)))
That will work, but it's not idiomatic clojure -- it is almost never idiomatic
clojure to have a def or defn within another defn. Also, you've used the syntax
that allows for multiple arglist/body pairs, although you only need one so the
extra layer of parentheses isn't necessary.
Here's how I might write it somewhat more idiomatically:
(defn avged
[x]
(let [sumed (reduce + x)
counted (count x)
result (/ sumed counted)]
result))
=> (avged [1 2 3 4])
5/2
=> (float (avged [1 2 3 4]))
2.5
>
> 2. What does the error message mean? and seeing this or similar again, how
> do I investigate to get a meaningful Clojure solution?
I think it means it's trying to call the value of sumed as a function. I'll
leave it to others to suggest ways of understanding Clojure error messages (and
just note for any of those others who have the ability to do something about
this that it sure would be great to be able to get stack backtraces with values
of locals regardless of IDE etc.).
> 3. Code Style, what can I do to improve readability and form?
Myself, I'd probably do it without any variables at all, and name everything
more meaningfully, e.g.:
(defn average-numbers
"Returns the average of the provided numbers."
[numbers]
(/ (reduce + numbers)
(count numbers)))
=> (average-numbers [1 2 3 4])
5/2
-Lee
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.