Saturday, April 3, 2010

SICP Series-chapter 1.3.1

In some languages, the function is a first class object.High order function means that you can use a function as a parameter or return value. Actually, high-order function has been existed in  many languages for long time, like Lisp,Python,Perl and Javascript. Now the C# also supports the high-order function and lambda expression. High order function is a powerful arm that makes your code more beautiful and shorter.
(defun cube (x)
 
(* x x x))
(defun sum (term a next b)
 
(if (> a b)
   
0
   
(+  (funcall term a)
       
(sum term (funcall next a) next b))))
(defun sum-integers (a b)
 
(sum #'identity a #'1+ b))
(defun pi-sum (a b)
 
(defun pi-term (x)
   
(/ 1.0 (* x (+ x 2))))
  (defun pi-next (x)
    (+ x 4))
  (sum #'pi-term a #'pi-next b))
(defun integral (f a b dx)
  (defun add-dx (x)
    (+ x dx))
  (* (sum f (+ a (/
dx 2.0)) #'add-dx b)
    dx
))
There is one thing that I have mentioned before. When we use a function as a parameter, you may need call the function in the function body. But you can’t just call it by placing the function name at the leftmost in a form. You need use funcall to tell the interpreter that this is a function.
1.29
(defun simpson-integral(f a b n)
 
(let ((h (float (/ (- b a) n))))
       (defun simpson-term(i)
              (let ((temp (funcall f (+ a (* h i)))))
                   (cond ((or (= i 0)
                              (= i n))
                          temp)
                         ((evenp i) (* 2 temp))
                         (t (* 4 temp)))))
       (* (/
h 3)
         
(sum #'simpson-term 0 #'1+ n))))



1.30
We have already meet this problem many time in previous posts, like the Fibonacci function we have implemented before.The basic algorithm is similar.
(defun sumv2(term a next b)
    (defun iter(a result)    
        (if (> a b)
            result
            (iter (funcall next a) (+ result (funcall term a)))))
(iter a 0))

1.31
It’s very easy to implement the product function, which is similar to sum function.
(defun product(term a next b)
 
(if (> a b)
     
1
     
(* (funcall term a)
         
(product term (funcall next a) next b))))
(defun productv2(term a next b)
 
(defun iter(a result)
         
(if (> a b)
             result
             
(iter (funcall next a) (* result (funcall term a)))))
 
(iter a 1))
(defun factorial(n)
 
(defun fact-aux(i)
         
(let ((deno 0)
             
(neo 0))
         
(cond ((evenp i) (progn (setq deno (+ i 1)) (setq neo (+ i 2))))
               
((oddp i) (progn (setq deno (+ i 2)) (setq neo (+ i 1)))))
         
(float (/ neo deno))))
 
(product #'fact-aux 1 #'1+ n))
1.32
(defun accumulator(combiner null-value term a next b)
 
(if (> a b)
     
null-value
     
(funcall combiner (funcall term a)
               
(combiner null-value term (funcall next a) next b))))
(defun accumulatorv2(combiner null-value term a next b)
 
(defun accumulator-iter (a null-value)
         
(if (> a b)
             
null-value
             
(accumulator-iter (funcall next a) (funcall combiner (funcall term a) null-value))))
 
(accumulator-iter a null-value))
(defun productv3(term a next b)
 
(accumulatorv2 #'* 1 term a next b))
Abstract is a very important concept in the programming. If you understand the core of the abstract, you get a powerful tool.Use the abstract, you can separate one complex function to many parts.Each part becomes easier and smaller. The powerful of Lisp makes this concept clear for many people.

No comments:

Post a Comment