Search code examples
lispcommon-lisp

Learning LISP - Defining a stdev function


I am very new to LISP (so forgive me for any dumb mistakes) and the first lab of the year states:

Define a function, STDEV that will compute the standard deviation of a list of numbers (look up formula)

I wrote this code but I don't know why it refuses to work:

(defun stdev (x)
  (sqrt (/ (apply '+ (expt (- x (/ (apply '+ x)
                                   (length x)))
                           2))
           (length x))))

(setq a '(1 2 3 4 5))

(STDEV a)

But on runtime it produces the error:

(1 2 3 4 5) is not a number

I believe that I have correctly emulated the standard deviation formula (though I wouldn't put it past myself to make a dumb mistake), but why does my program not like the list of numbers that I give it to evaluate? It is most likely a simple mistake with inputs from this new style of coding but any and all help is greatly appreciated!


Solution

  • Use indentation. I've edited your question:

    (defun stdev (x)
      (sqrt (/ (apply '+ (expt (- x (/ (apply '+ x)
                                       (length x)))
                               2))
               (length x))))
    

    expt returns a number. You call (apply '+ some-number)?

    Also you subtract a number from a list.

    Why?

    Generally I would recommend to use a Lisp listener (aka REPL) to get to working code:

    Compute the mean value:

    CL-USER 21 > (let ((l (list 1 2 3 4 5)))
                   (/ (reduce #'+ l)
                      (length l)))
    3
    

    Subtract the mean value and square using mapcar:

    CL-USER 22 > (mapcar (lambda (item)
                           (expt (- item 3) 2))
                         (list 1 2 3 4 5))
    (4 1 0 1 4)
    

    Compute the variance as the mean value of above:

    CL-USER 23 > (let ((l (list 4 1 0 1 4)))
                   (/ (reduce #'+ l)
                      (length l)))
    2
    

    Take the square root to get the standard deviation:

    CL-USER 24 > (sqrt 2)
    1.4142135
    

    Then you only need to assemble it into a few functions: average, variance and standard-deviation.