You can express summation using foldl
(define (summation li avg)
(foldl (lambda (x acc)
(+ acc
(expt (- x avg)
2)))
0
li))
While these procedures you supply here seem simple, you should be considering the consequences of their implementation. For example, I'm sure you could write your own length function
(define (length li)
(if (null? li)
0
(+ 1 (length (cdr li)))))
You use (apply + li) to calculate a your input list's sum, but I'm sure you realize that's a clever replacement for our simple recursive solution
(define (sum li)
(if (null? li)
0
(+ (car li)
(sum (cdr li)))))
Given sum and length, we implement average
(define (average li)
(/ (sum li)
(length li)))
Do you see the problem here? sum and length both iterate through the input list. Then we go on to write sd...
(define (sd li)
(sqrt (/ (summation li
(average li))
(- (length li)
1))))
Do you see how the problem has worsened? We know average already steps through the input list li twice, summation steps through it again, and notice there's another call to length – we've iterated thru li 4 times before sd can return its result
Let's rewind a little bit. Looking at average, wouldn't it be nice if there was some way we could sum the elements of li and count them simultaneously? Well we can!
(define (average li (return /))
(if (null? li)
(return 0 0)
(average (cdr li)
(lambda (sum count)
(return (+ sum (car li))
(+ count 1))))))
(average '(1)) ;; 1
(average '(1 2)) ;; 1 1/2
(average '(1 2 3)) ;; 2
(average '()) ;; Error: division by zero
Using this technique, you can perform transformations of virtually any complexity. Writing sd using this style is left as an exercise for the reader.