匿名函式與「有名函式」
scheme中匿名函式使用 lambda 函式實現,格式為:
(lamdba )
例如:
(lambda (i) (+ i 3)) ;接受乙個引數,返回它與3的和
呼叫方法為:
> ((lambda (i) (+ i 3)) 2)
5
而有名函式的定義方式和呼叫方式如下:
(define () ;格式
)(define (function n) ;例子
(+ n 3))
(function 4) ;呼叫 function
>7
用匿名函式實現遞迴
遞迴是指乙個函式呼叫自身的過程,一般是通過函式名呼叫,但是匿名函式沒有名稱,即無法通過函式名直接呼叫
使用匿名函式實現遞迴主要通過加入乙個引數的方式,例如:
((lambda (fn n fn)) ;接受乙個引數10,並把它變為1
(lambda (a f)
(if (= a 1)
a(f (- a 1) f)))
10)
這個例子挺蠢的:直接接受引數然後返回1就好了,但它是乙個完整並且可以執行的匿名函式遞迴,可以用這個例子理解匿名函式遞迴的實現方法。下面是乙個匿名函式實現斐波那契數列的例子,它能接受乙個引數 n ,並返回第n個斐波那契數:
((lambda (fn n) ;返回第十個斐波那契數
(fn n 1 0 fn))
(lambda (count new old f)
(if (= count 1)
new(f (- count 1)
(+ new old)
newf)))
10)
分析
這種使用匿名函式遞迴的方法雖然沒有使用 define 對函式命名,但不難看出,其實這樣的方法還是隱式的給函式命名: 第乙個lambda函式中的 fn引數。把第二個lambda函式作為引數 fn 傳遞給第乙個 lambda,然後讓 fn 呼叫 fn,上面的斐波那契函式等價於下面這段**:
(let ((fn
(lambda (count new old)
(if (= 1 count)
new(fn (- count 1)
(+ new old)
new))))
(n 10))
(fn n 1 0))
又等價於:
(define (fn count new old)
(if (= count 1)
new(fn (- count 1)
(+ new old)
new)))
(fn 10 1 0)
總結
函式接受引數, 可以視為隱式的將實際引數的值(例如上面的 10,第二個lambda)賦值給形式引數(上面的 fn,count,new,old)。匿名函式遞迴時,用接受引數的方法隱式的給函式「起名」,而「有名函式」則使用 define正大光明的給函式起名
正常情況下還是使用 let 或 define 給函式起名再遞迴,會使**更加明了
匿名函式遞迴
lambda是匿名函式,因為沒有名字,也沒有關鍵字引用自身,因此遞迴的編碼就成了問題。一 最簡單有效的方案是 func f null 變數須先賦值才能使用 f n n 0?1 n f n 1 f 11 39916800 有人擔心f會被惡意修改,因為就是乙個委託變數,而且認為f是委託,而不是匿名函式自...
匿名函式遞迴
lambda是匿名函式,因為沒有名字,也沒有關鍵字引用自身,因此遞迴的編碼就成了問題。一 最簡單有效的方案是 func f null 變數須先賦值才能使用 f n n 0?1 n f n 1 f 11 39916800 有人擔心f會被惡意修改,因為就是乙個委託變數,而且認為f是委託,而不是匿名函式自...
遞迴,匿名函式
目錄匿名函式 函式的巢狀呼叫 函式巢狀函式。函式的遞迴呼叫 它是一種特殊的巢狀呼叫,但是它在呼叫乙個函式過程中,有直接間接呼叫了自身。def foo print from foo foo foo 進入死迴圈def bar print from bar foo def foo print from f...