4

I've just begun to teach myself clojure and I'm having fun. However trouble began when I began to exec this function I wrote!

It's a simple function that accepts multiple number of arguments & returns the difference between the last and the first arguments.

(defn diff-last-first 
   "gets the difference between the last & the first arguments" 
   [& args] 
   (- (get args (- (count args) 1)) (get args 0)))

I know that I can simply use the last function to get the last element of args, but I'm not able to understand why this is throwing a NullPointerException when I execute (diff-last-first 1 2 3)

3 Answers3

3

If you do want to access the nth value of a list, you can use nth:

(defn diff-last-first [& args]
   (- (nth args (dec (count args)))
      (nth args 0)))

But of course, as you pointed out in your question, it is more idiomatic to use first and last:

(defn diff-last-first [& args]
  (- (last args) 
     (first args)))
Daniel Neal
  • 4,165
  • 2
  • 20
  • 34
2

(get (list :foo) 0) evaluates to nil.

Lists are not supposed to be accessed by index: it is a common design decision in Clojure to prevent such inefficiencies.

deprecated
  • 5,142
  • 3
  • 41
  • 62
  • But `(- (get args (- (count args) 1)) (get args 0))` does return the correct answer! Only when I put it in the expression of a function it is throwing **NPE** – Raghu Kanchiraju Aug 13 '13 at 13:12
  • 1
    Huh? Lists in Clojure aren't supposed to be accessed by index? – Chiron Aug 13 '13 at 13:13
  • @RaghuKanchiraju - I guess you tried that expression with `args` bound to a vector (not a list!), in the REPL? – deprecated Aug 13 '13 at 13:15
  • @vemv Yes! It was a vector (array) – Raghu Kanchiraju Aug 13 '13 at 13:18
  • @RaghuKanchiraju then there you have your answer :) just keep in mind that lists, arrays and vectors are different things in Clojure. – deprecated Aug 13 '13 at 13:19
  • @Chiron Nope - that's why trying so returns nil (as per `getFrom` in clojure.lang.RT) – deprecated Aug 13 '13 at 13:25
  • 1
    Regarding accessing lists by index -- `get` does not work because lists are not associative. That you have to use `nth` to access a seq by index should be a reminder that performance is linear. – A. Webb Aug 13 '13 at 13:48
0

Ok, Got it!

@vemv was right! [& args] is a list and hence (get args 0) returns nil

Whereas (defn get-l-f [args] (- (get args (- (count args) 1)) (get args 0))) works as expected as args is a vector here!