使用高階函數 可以做出很多powerful的事請 例如異步編程 所謂異步 舉個栗子就像https://www.zhihu.com/question/19732473所說的
老張愛喝茶,廢話不說,煮開水。
出場人物:老張,水壺兩把(普通水壺,簡稱水壺;會響的水壺,簡稱響水壺)。
1 老張把水壺放到火上,立等水開。(同步阻塞)老張覺得自己有點傻
2 老張把水壺放到火上,去客廳看電視,時不時去廚房看看水開沒有。(同步非阻塞)老張還是覺得自己有點傻,於是變高端了,買了把會響笛的那種水壺。水開之後,能大聲發出嘀~~~~的噪音。
3 老張把響水壺放到火上,立等水開。(異步阻塞)老張覺得這樣傻等意義不大
4 老張把響水壺放到火上,去客廳看電視,水壺響之前不再去看它了,響了再去拿壺。(異步非阻塞)
老張覺得自己聰明了。
這種「不會馬上回傳」的性質,在某些更新頻繁且大量的情況下很有用.就例如ajax,如果一個網站有大量資料且前後相關,一般的逐頁搜索會很沒效率而且很不方便.但如果可以用一些簡單操作逐批資料加載 整個網站就變得人性化多了
至於異步要如何控制呢,這就是我要今天記下的題目:Continuation-passing style(CPS)
所謂CPS 顧名思義就是一種編程的style 在這種style底下 每個動作都會回傳一個函數 這個函數會呼叫下個函數直至動作完結 這個呼叫的函數大多是呼叫他的父函數自身 形成一種連續的時間線 著名的函數式語言Haskell在發明初期都是用CPS處理I/O 以下是一個node.js呼叫sqlite例子
//file:test.js var sqlite3 = require('sqlite3'); var db = new sqlite3.Database('/tmp/1.db',function() { db.run("create table test(name varchar(15))",function(){ db.run("insert into test values('hello,world')",function(){ db.all("select * from test",function(err,res){ if(!err) console.log(JSON.stringify(res)); else console.log(err); }); }) }); });來源http://blog.csdn.net/chuanqi305/article/details/17930179
node.js用的是GOOGLE的V8引擎,最大特點是對異步的支援,官方聲稱可以「以同步的方式進行異步操作」或許以上的代碼有些人會覺得奇怪用這種方式有什麼好處 先來個負面教材好了
var sqlite3 = require('sqlite3'); var db = new sqlite3.Database('/tmp/1.db',false); db.run("create table test(name varchar(15))",false); db.run("insert into test values('hello,world')",false); db.all("select * from test",function(err,res){ if(!err) console.log(JSON.stringify(res)); else console.log(err); });以上的代碼在執行到第4句的時候會拋出一個錯誤 從錯誤訊息裡會看到process找不到一個名為test的table
是為什麼呢 原因是因為 第3句還未執行完成的時候 第4句就會開始執行 所以node找不到table
回想第一個例子 使用這方式的用處是 當sql語句執行完成時 參數裡的callback function才會繼續執行 是不是恍然大悟呢?XD
異步還有很多種實現方式,如lua中的協程(coroutine) ,go中的goroutines(node.js反轉版)有機會再記下來好了
注:以下內容純玩樂性質 對編程毫無用處 認真魔人請戴眼罩觀看
說起高階函數 還有很多很有趣的用法
有一種類似CPS的lambda實例叫y combinator ,和 Self Application Function是一樣的東東
廢話不多說~去圖
有一種類似丘奇數的實例 使用的是lambda的進化版SKI calculus
Ix = x Kxy = x Sxyz = xz(yz)Self-application and recursion:
SIIα = Iα(Iα) = αα SII(SII) = I(SII)(I(SII)) = I(SII)(SII) = SII(SII) (S(Kα)(SII))β = Kαβ(SIIβ) = α(SIIβ) = α(ββ) β = S(Kα)(SII) SIIβ = ββ = α(ββ) = α(α(ββ)) = ...The reversal expression:
S(K(SI))Kαβ → K(SI)α(Kα)β → SI(Kα)β → Iβ(Kαβ) → Iβα → βαBoolean logic:
T = K Kxy = x F = SK SKxy = Ky(xy) = y NOT = (F)(T) = (SK)(K) (T)NOT = T(F)(T) = F (F)NOT = F(F)(T) = T OR = T = K AND = F = SKfurthermore:https://en.wikipedia.org/wiki/SKI_combinator_calculus
沒有留言:
張貼留言