教材有時候依照學生的基礎。從0講起;有時候給出一個大圖,而後具體地逐一介紹。html
本文或同窗們寫學習筆記時。要依照後者進行概括。編程
函數,是對一些數的複合操做,而且不依賴特定的數。如
(define (cube x) (* x x x))數據結構
它不針對某個數如3,而是對所有的參數數據求其立方。編程語言
由此。它是對ide
(* 5 5 5)函數
(* x x x) ; 這裏x爲實參
的抽象,而(* 5 5 5)等則編寫爲函數的應用( cube 5)。學習
注意,函數cube僅僅是將數做爲參數。假設能夠將函數做爲還有一個函數的參數,會是一種什麼場面呢?spa
編程語言通常會對其元素的使用方式。作出一些限制。而受到的限制最少的元素屬於第一階(first-class)。設計
第一階元素擁有的特權包含:
用變量命名
做爲函數的參數
由函數返回
(可以包括在數據結構中)
Java的基本類型和引用類型。都是第一階元素。但是。函數在Scheme中如同其基本數據類型同樣,徹底然全地是第一階元素。
因此,當把函數做爲參數、返回值來使用的時候,就有了更高階的函數。操做函數的函數即爲高階函數。指針
在數學中。序列求和的sigma (∑)記法/符號,就是一個樣例。
不管f(x)是什麼。高階函數∑求和。
假定咱們有3個詳細的求和函數。
1)sum-integers求代數和(從a到b)
(define (sum-integersa b)
(if (> ab)
0
(+ a(sum-integers (+ a 1) b))))
2)sum-cubes求立方和,
3)pi-sum依照公式
求出л/8.
(define (pi-sum a b)
(if (> ab)
0
(+ (/ 1.0 (* a (+ a 2)))(pi-sum (+ a 4) b))))
現在考慮設計一個高階函數,表達∑符號。顯然,除了參數a。b外,還需要指定∑中的項和變化規律,咱們以term描寫敘述∑中的項,而next描寫敘述依照變化規律獲得的下一項。則
(define (sum term next a b) ;我喜歡a、b挨着
(if (> ab)
0
(+(term a)
(sumterm next (next a) b))))
定義的sum爲∑求和這一高階函數。
高階函數sum中,term和next都是函數形參,相似C的函數指針。若是咱們在sum基礎上定義求代數和。就需要提供term和next將要綁定的函數。
代數和的term,是一個恆等函數(identity),next是一個自增函數。
(define (identity x) x)
(define (inc n) (+ n 1))
因而,不需要單獨定義sum-integers。而是應用高階函數sum。獲得sum-integers:
(define (sum-integers a b)
(sum identity inc a b))
(sum-integers 1 10)
另外。對於一次性的小函數,使用lambda表達式很緊湊。(在這裏不是要點)
高階函數sum的返回值是一個數,高階函數強大之處。可以將某些函數做爲輸入,而又返回一個函數——函數轉換。
(define (transf f)
(lambda(a)(+ a (f a)) ) )
(define (square x)
(* x x) )
((transf square) 2)
函數transf的做用是對函數f進行平移,其返回值是由lambda定義的匿名函數。當將匿名函數應用到2時。獲得的是2+f(2)。
高階函數transf處理做爲參數的函數f時,將它視爲僅僅有一個參數的函數,如函數應用(f a)所暗示的。
但是做爲參數的f,並無說明這一信息。對於兩個參數的op (define (op x y) (* x y) ) 將它應用到transf中是不該該的。解釋器對於(transf op)的輸出,爲何不是一個錯誤?固然。進一步應用會出錯。 ((transf op) 5) ;要2個參數 ((transf op) 1 5) ;要一個參數