停機(jī)問題與Y Combinator(一)

前言

上個月月末的時(shí)候外构,看了《The Little Schemer》的第九章,第九章就是在講停機(jī)問題和Y組合子播掷。感覺很有意思审编,Y組合子真的是一個很神奇又有趣的東西,以至于MIT數(shù)學(xué)系的系徽就用的是Y組合子歧匈。Y組合子的發(fā)現(xiàn)者Haskell B.Curry把Y組合子紋在手臂上垒酬,他覺得自己撿了個大便宜。什么件炉?你不知道這個人勘究?我也不知道,但是學(xué)編程的Haskell這個單詞應(yīng)該很眼熟吧斟冕,沒錯就是用這個人的名字命名的Haskell語言口糕。可見此人必定是大魔法師啊磕蛇,魔法師景描,你懂得。手臂上封印Y組合子秀撇,手中莫名的多了汽油和火把超棺。

其實(shí)我也是魔法師這個高貴職業(yè)中得一員,Lv.22即將升到Lv.23呵燕。

MIT數(shù)學(xué)系系徽
MIT數(shù)學(xué)系系徽

停機(jī)問題

首先是停機(jī)問題棠绘,我們來思考這樣一個問題:是否會有這樣一個程序告訴我們一個函數(shù)對于它的每一個輸入都能夠返回一個值?什么意思?看我們的題目弄唧,停機(jī)問題啊适肠,一個程序返回了那就是停機(jī)了,如果一直運(yùn)行下去候引,那就是不停機(jī)侯养。什么沒見過一直運(yùn)行下去的程序?去寫個函數(shù)澄干,無參逛揩,自己調(diào)自己你看它能返回不?好麸俘,現(xiàn)在停機(jī)的概念已經(jīng)清楚了辩稽,那么我們問題是什么?就是說會不會有這么一個程序从媚,我們傳入另一個程序逞泄,它返回true或false,如果是true拜效,那就是說這個程序停機(jī)喷众,如果是false那就是說這個程序不停機(jī),問題清楚了吧紧憾。所以有還是沒有呢到千?好,我知道你們都會說沒有赴穗,但是我還是要剛一波憔四,我就說有。假如有應(yīng)該是這個樣子般眉,參數(shù)是一個函數(shù)f了赵,返回值應(yīng)該是true或者false。我們用Scheme來定義一下這個充滿魔法自帶火把的函數(shù):

(define will-stop?
  (lambda (f)
    ...))

在這里簡單的說一下Scheme的語法:
define就是起個名甸赃,函數(shù)的定義:很簡單柿汛,lambda關(guān)鍵字,括號里面是參數(shù)表辑奈,然后是函數(shù)體,就是下面的樣子已烤。

(define add
  (lambda (x y)
    (+ x y)))

(define <fun-name>
  (lambda (<args>)
    <body>))

函數(shù)的調(diào)用:就是先寫操作符鸠窗,然后寫實(shí)參,實(shí)際上就是前綴表達(dá)式胯究。寫法就像下面的樣子:

(+ 1 2)

((lambda (x y)
   (+ x y)) 1 2)

(<op> <args>)

這里必須吹一波Scheme語法稍计,簡潔到令人感動。Lisp語言誕生于1958年裕循,至今還很活躍臣嚣,如運(yùn)行在JVM上的Clojure,我感覺語法有很大的功勞。那些號稱語法簡潔的語言如某Go蚕涤,看了看噪裕,感覺也就那樣。

吹B結(jié)束怎虫,回到我們之前的問題暑认,現(xiàn)在我們這個will-stop?函數(shù)已經(jīng)寫好了。好我們寫兩個函數(shù)驗(yàn)驗(yàn)貨大审,先寫一個可以停機(jī)的吧蘸际。

(define length
  (lambda (l)
    (cond
     ((null? l) 0)
     (else
      (+ 1 (length (cdr l)))))))

這個函數(shù)接受一個list作為參數(shù),就是數(shù)據(jù)結(jié)構(gòu)中的鏈表徒扶。然后呢如果是空鏈表就返回0粮彤,否則的話返回(+ 1 (length (cdr l))),cdr就是除去鏈表第一個元素形成的新的鏈表姜骡。所以這個函數(shù)是對的吧导坟,傳入一個list,返回它的元素個數(shù)也就是節(jié)點(diǎn)的個數(shù)溶浴,這個值就是list的長度乍迄。就像Java中List的size方法一樣。顯然對于一個合法的參數(shù)士败,length函數(shù)是可以停機(jī)的闯两。什么你說無窮流?我認(rèn)為它不合法:)×陆現(xiàn)在我們將length傳給will-stop?漾狼,它就會返回true。現(xiàn)在再來想一個不會停機(jī)的函數(shù)饥臂,這個簡單逊躁,遞歸啊隅熙!看下面的函數(shù)稽煤,以x為參數(shù),然后函數(shù)中再用自己去調(diào)用x囚戚,這樣它就會一直的運(yùn)行下去酵熙。所以(will-stop? eternity)會返回false。好驰坊,現(xiàn)在我們充滿魔法的的will-stop匾二?函數(shù)已經(jīng)可以工作了。說了這么多,其實(shí)就是假設(shè)我們有這樣的程序察藐,反證法么皮璧,上學(xué)的時(shí)候證明題做不出來就反證啊分飞!

(define eternity
  (lambda (x)
    (eternity x)))

現(xiàn)在我們利用現(xiàn)有的will-stop?函數(shù)來寫另一個函數(shù):

(define last-try
  (lambda ()
    (and (will-stop? last-try)
         (eternity '())))

這里說一下Scheme中的and悴务,如果第一個表達(dá)式返回false,就返回false浸须。如果前面的的表達(dá)式都返回的true惨寿,就返回最后一個表達(dá)式。所以看一下last-try這個函數(shù)删窒,無參數(shù)裂垦,函數(shù)體的意思是,如果last-try停機(jī)我就調(diào)用eternity函數(shù)肌索,如果last-try不停機(jī)我就返回false蕉拢。

沒錯吧?是這個意思吧诚亚,好記自位弧!

有沒有發(fā)現(xiàn)哪里不對站宗?我們調(diào)用一下(will-stop? last-try)闸准,完了,崩了梢灭!我們充滿魔法的will-stop?總會給我們一個答案夷家,如果是true,那么我們認(rèn)為last-try是可以停機(jī)的敏释。但是我們上面有說過库快,last-try函數(shù)如果停機(jī),就會調(diào)用eternity函數(shù)钥顽,就不會停機(jī)义屏。如果是不可停機(jī)的,即(will-stop? last-try)返回的是false蜂大,也就是說充滿魔法的程序告訴我們last-try是不會停機(jī)的闽铐。但是我們就看last-try的函數(shù)體,如果last-try不停機(jī)奶浦,就直接返回false兄墅,停機(jī)了。财喳。察迟。

Ok!矛盾了耳高,所以說不存在這樣一個程序扎瓶。原來寫不出來是因?yàn)椴淮嬖冢皇俏覀儾粔蚺1泼谇梗睦镞@就好受多了概荷,感謝圖靈和哥德爾,66666碌燕!

好误证,停機(jī)問題到此結(jié)束,先用這個簡單的問題來醒醒腦修壕。

下集預(yù)告

第二篇文章會用Scheme語言一步一步的推倒出Y Combinator愈捅,敬請期待:)。

還得說一嘴慈鸠,網(wǎng)上總有人說一下午看完了Dan的《The Little Schemer》蓝谨,這幫人真的挺low的。這書雖然寫的像個小人書一樣青团,而且也就兩百來頁譬巫,但是進(jìn)入第八章之后,瞬間高能督笆!一下午都不見得看得完一章芦昔,你要說你一下午看完了《Thinking in Java》,那我信:)娃肿。人越缺少什么就越愛炫耀什么咕缎,骨子里還是自卑的。所以總是向別人炫耀自己多么聰明的咸作,對吧:)锨阿。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市记罚,隨后出現(xiàn)的幾起案子墅诡,更是在濱河造成了極大的恐慌,老刑警劉巖桐智,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件末早,死亡現(xiàn)場離奇詭異,居然都是意外死亡说庭,警方通過查閱死者的電腦和手機(jī)然磷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刊驴,“玉大人姿搜,你說我怎么就攤上這事寡润。” “怎么了舅柜?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵梭纹,是天一觀的道長。 經(jīng)常有香客問我致份,道長变抽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任氮块,我火速辦了婚禮绍载,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘滔蝉。我一直安慰自己击儡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布蝠引。 她就那樣靜靜地躺著曙痘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪立肘。 梳的紋絲不亂的頭發(fā)上边坤,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機(jī)與錄音谅年,去河邊找鬼茧痒。 笑死,一個胖子當(dāng)著我的面吹牛融蹂,可吹牛的內(nèi)容都是我干的旺订。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼超燃,長吁一口氣:“原來是場噩夢啊……” “哼区拳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起意乓,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤樱调,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后届良,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笆凌,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年士葫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了乞而。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡慢显,死狀恐怖爪模,靈堂內(nèi)的尸體忽然破棺而出欠啤,到底是詐尸還是另有隱情,我是刑警寧澤屋灌,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布跪妥,位于F島的核電站,受9級特大地震影響声滥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜侦香,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一落塑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧罐韩,春花似錦憾赁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至矾睦,卻和暖如春晦款,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背枚冗。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工缓溅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赁温。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓坛怪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親股囊。 傳聞我的和親對象是個殘疾皇子袜匿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)稚疹,斷路器居灯,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • //Clojure入門教程: Clojure – Functional Programming for the J...
    葡萄喃喃囈語閱讀 3,629評論 0 7
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法内狗,內(nèi)部類的語法穆壕,繼承相關(guān)的語法,異常的語法其屏,線程的語...
    子非魚_t_閱讀 31,597評論 18 399
  • http://python.jobbole.com/85231/ 關(guān)于專業(yè)技能寫完項(xiàng)目接著寫寫一名3年工作經(jīng)驗(yàn)的J...
    燕京博士閱讀 7,557評論 1 118
  • 對于吃貨來說喇勋,城市的標(biāo)志是當(dāng)?shù)靥厣男〕裕洃浺粋€城市偎行,必冠之小吃的后綴川背,方才津津有味樂此不疲贰拿。比如蘭州拉面、西安...
    寧黛閱讀 605評論 0 1