亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

軟件開發詳解:從Continuation說起

2019-11-18 11:58:55
字體:
來源:轉載
供稿:網友

  說起Continuation,象我這樣的大多數從C, Basic, Pascal起步的程序員可能都不清楚。但是這個概念在functional language 社區卻好象是常識一樣,很多人在討論問題的時候總是假設你已經知道了continuation的基本概念,什么Call-CC什么的都不加解釋就直接引用。于是,假如不知道continuation到底指的是什么,簡直就無法理解他們在說什么。
  
  于是,最近花了點時間研究了continuation的概念。
  
  剛才恍然小悟了MonadCont的實現機制,作為慶祝,在此和大家共享一下我的理解,然后再回頭討論一下continuation在imperative語言和C++中的可能應用。
  
  所謂continuation,其實本來是一個函數調用機制。
  
  我們熟悉的函數調用方法都是使用堆棧,采用Activation record或者叫Stack frame來記錄從最頂層函數到當前函數的所有context。一個frame/record就是一個函數的局部上下文信息,包括所有的局部變量的值和SP, PC指針的值(通過靜態分析,某些局部變量的信息是不必保存的,非凡的如尾調用的情況則不需要任何stack frame。不過,邏輯上,我們認為所有信息都被保存了)。函數的調用前往往伴隨著一些push來保存context信息,函數退出時則是取消當前的record/frame,恢復上一個調用者的record/frame。
  
  象pascal這樣的支持嵌套函數的,則需要一個額外的指針來保存父函數的frame地址。不過,無論如何,在任何時候,系統保存的就是一個后入先出的堆棧,一個函數一旦退出,它的frame就被刪除了。
  
  Continuation則是另一種函數調用方式。它不采用堆棧來保存上下文,而是把這些信息保存在continuation record中。這些continuation record和堆棧的activation record的區別在于,它不采用后入先出的線性方式,所有record被組成一棵樹(或者圖),從一個函數調用另一個函數就等于給當前節點生成一個子節點,然后把系統寄存器移動到這個子節點。一個函數的退出等于從當前節點退回到父節點。
  
  這些節點的刪除是由garbage collection來治理。假如沒有引用這個record,則它就是可以被刪除的。
  
  這樣的調用方式和堆棧方式相比的好處在哪里呢?
  
  最大的好處就是,它可以讓你從任意一個節點跳到另一個節點。而不必遵循堆棧方式的一層一層的return方式。比如說,在當前的函數內,你只要有一個其它函數的節點信息,完全可以選擇return到那個函數,而不是循規蹈矩地返回到自己的調用者。你也可以在一個函數的任何位置儲存自己的上下文信息,然后,在以后某個適當的時刻,從其它的任何一個函數里面返回到自己現在的位置。
  
  Scheme語言有一個CallCC (call with current continuation)的機制,也就是說:取得當前的continuation,傳遞給要call的這個函數,這個函數可以選擇在適當的時候直接return到當前的continuation。
  
  經典的應用有:exception,back-tracking算法, coroutine等。
  
  應用continuation對付exception是很明顯的,只要給可能拋出異常的函數一個外面try的地方的continuation record,這個函數就可以在需要的時候直接返回到try語句的地方。
  
  Exception-handling也可以利用continuation。c++等語言普遍采用的是碰到exception就直接中止當前函數的策略,但是,還有一種策略是答應resume,也就是說,出現了異常之后,有可能異常處理模塊修復了錯誤發生的地方然后選擇恢復執行被異常中斷了的代碼。被異常中斷的代碼可以取得當前的continuation,傳遞給異常處理模塊,這樣當resume的時候可以直接跳到出現異常的地方。
  
  Back-tracking算法也可以用類似的方法,在某些地方保存當前的continuation,然后以后就可以從其它的函數跳回當前的語句。
  
  Coroutine是一個并行計算的模型。它讓兩個進程可以交替執行。典型的coroutine的應用例子如consumer-PRodUCer。比如說:
  
  Code:Producer ( c ):
  
  Loop:
  
  Produce;
  
  CallCC c
  
  Consumer( p ):
  
  Loop:
  
  Consume;
  
  Callcc p
  
  這兩個線程接受對方的continuation,在需要交出控制的時候,就把自己的continuation傳遞給對方。如此,兩者就可以交替執行,而不需要返回。
  
  Continuation機制的優化始終不是一個trivial的問題,實際上采取continuation的語言不多。而且,continuation調用方式依靠垃圾收集,也不是c/c++這類中低級的語言所愿意采用的。
  
  不過,continuation的思想仍然是有其用武之地的。有一種設計的風格叫做continuation-passing-style。它的基本思想是:當需要返回某些數據的時候,不是直接把它當作函數的返回值,而是接受一個叫做continuation的參數,這個參數就是一個call-back函數, 它接受這個數據,并做需要做的事情。
  
  舉個例子:
  
  Code:X = f();
  
  Print x;
  
  把它變成continuation-passing-style, 則是:
  
  f(print);
  
  F()函數不再返回x, 而是接受一個函數,然后把本來要返回的x傳遞給這個函數。
  
  這個例子也許看上去有點莫名其妙:為什么這么做呢?對Haskell這樣的語言,一個原因是:
  
  當函數根據不同的輸入可能返回不同類型的值時,用返回值的話就必須設計一個額外的數據結構來處理這種不同的可能性。比如:
  
  一個函數f(int)的返回值可能是一個int, 兩個float或者三個complex,那么,我們可以這樣設計我們的函數f.
  
  Code:F:: Int -> (Int->a) -> (Float->Float->a) -> (Complex->Complex->Complex->a) -> a
  
  這個函數接受一個整形參數,三個continuation回調用來處理三種不同的返回情況,最后返回這三個回調所返回的類型。
  
  另一個原因:對模擬imperative風格的monad,可以在函數中間迅速返回(類似于C里面的return或者throw)
  
  對于C++,我想,除了處理不同返回類型的問題,另一個應用可以是避免返回值的不必要拷貝。雖然c++現在有NRV優化,但是這個優化本身就很含混,各個編譯器對NRV的實現也不同。C++中的拷貝構造很多時候是具有副作用的,作為程序員,不知道自己寫的的副作用到底是否被執行了,被執行了幾次,總不是一個舒適事。
  
  而continuation-passing-style,不依靠于任何偏僻的語言特性,也不會引入任何的模棱兩可,也許可以作為一個設計時的選擇。舉個例子, 對于字符串的拼接,假如使用continuation-passing-style如下:
  
  Code:Template<class F>
  
  Void concat(const string& s1, const string& s2, F ret){
  
  String s(s1);
  
  S.append(s2);
  
  ret(s);//此處,本來應該是return(s),但是我們把它變成ret(s)。
  
  }
  
  我們就可以很安心地說,我們此處沒有引入任何不必要的拷貝,不論什么編譯器。
  
  當然,continuation style的問題是,它不如直接返回值直觀,類型系統也無法保證你確實調用了ret(s)。而且,它需要一個function object,c++又不支持lamda,定義很多trivial的functor也會讓程序變得很難看。
  
  利弊如何,還要自己權衡。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品亚洲一区二区| 国产91久久婷婷一区二区| 欧美精品免费播放| 日韩女在线观看| 不用播放器成人网| 亚洲片在线观看| 欧美在线观看日本一区| 亚洲美女在线观看| 九九久久久久99精品| 日韩少妇与小伙激情| 91精品国产高清自在线| 久久久久国产视频| 日韩精品视频在线观看网址| 亚洲黄色免费三级| 国产色婷婷国产综合在线理论片a| 亚洲欧美综合另类中字| 亚洲色在线视频| 日韩亚洲精品视频| 久久99国产精品久久久久久久久| 欧美疯狂性受xxxxx另类| 久久久日本电影| 色樱桃影院亚洲精品影院| 在线视频国产日韩| 日韩精品一区二区三区第95| 国产亚洲欧美日韩美女| 国产免费一区二区三区在线能观看| 日韩精品视频在线免费观看| 日韩精品有码在线观看| 久久久久久高潮国产精品视| 欧美亚洲在线视频| 国产日韩欧美视频在线| 国产精品嫩草视频| 日韩av免费网站| 日韩高清电影免费观看完整| 久久久久999| 日韩福利视频在线观看| 日韩电影中文字幕| 午夜精品一区二区三区在线视频| 国产精品视频一区二区三区四| 日韩极品精品视频免费观看| 精品视频偷偷看在线观看| 性色av一区二区三区在线观看| 欧美激情中文网| 亚洲欧美国产精品专区久久| 成人精品在线视频| 亚洲视频在线视频| 久久深夜福利免费观看| 欧美日韩在线视频观看| 欧美激情精品久久久久久久变态| 日韩免费在线视频| 久久精品国产2020观看福利| 青青草精品毛片| 久久久久久久久久久免费精品| 91精品国产自产在线观看永久| 美日韩精品免费观看视频| 91香蕉电影院| 国产一区二区三区在线看| 国产在线高清精品| 97超碰国产精品女人人人爽| 国产精品小说在线| 亚洲人午夜精品| 精品久久久久久久大神国产| 国产综合在线观看视频| 国产午夜精品美女视频明星a级| 神马国产精品影院av| 国产综合香蕉五月婷在线| 亚洲片av在线| 久久久久在线观看| 国产一区二区三区中文| 国产一区二区三区毛片| 亚洲精品永久免费精品| 国产精品露脸自拍| 久久久久久久久亚洲| 亚洲人成自拍网站| 久久精品国产亚洲| 亚洲国产日韩欧美在线图片| 日韩精品视频三区| 国内揄拍国内精品| 久久久久中文字幕| 国产精品欧美日韩| 亚洲视频在线观看| 国产97在线亚洲| 久久精品国产久精国产思思| 久久精品国产成人精品| 久久精品国产成人| 日本免费一区二区三区视频观看| 欧美午夜影院在线视频| 亚洲一区二区中文| 成人免费视频xnxx.com| 亚洲精品v欧美精品v日韩精品| 国模私拍一区二区三区| 国产福利精品av综合导导航| 欧美寡妇偷汉性猛交| 国产亚洲视频中文字幕视频| 欧美xxxx18性欧美| 日韩中文av在线| 国产精品激情av在线播放| 久久av红桃一区二区小说| 国产精品美女免费看| 国产精品福利在线观看网址| 69av在线视频| 日韩人在线观看| 国产精品成人观看视频国产奇米| 欧美在线播放视频| 日韩精品免费观看| 国模视频一区二区三区| 欧美在线日韩在线| 欧美www在线| 亚洲免费av网址| 亚洲aaa激情| 亚洲日本aⅴ片在线观看香蕉| 久久久999精品视频| 日韩大片在线观看视频| 久久男人av资源网站| 一区二区在线视频| 国产中文字幕亚洲| 91精品久久久久久久久久久久久久| 亚洲国产精品国自产拍av秋霞| 国产精品视频yy9099| 91免费视频国产| 欧美电影第一页| 91久久国产综合久久91精品网站| 欧美成人黑人xx视频免费观看| 日本精品久久久久影院| 日本欧美在线视频| 欧美国产第一页| 成人在线视频网| 久久精品99国产精品酒店日本| 亚洲一级片在线看| 另类专区欧美制服同性| 欧美中文在线字幕| 一区二区国产精品视频| 欧美自拍大量在线观看| 亚洲综合成人婷婷小说| 国产精品第10页| 日韩欧美亚洲国产一区| 亚洲精品免费av| 国产精品白丝av嫩草影院| 久久久久久中文| 91久久精品一区| 夜夜嗨av一区二区三区免费区| 98精品国产高清在线xxxx天堂| 国产一区二区三区直播精品电影| 欧美电影免费观看高清| 中文字幕成人在线| 亚洲高清在线观看| 亚洲国产精品热久久| 91色在线视频| 精品国产乱码久久久久久婷婷| 欧美午夜精品久久久久久浪潮| 久久福利网址导航| 亚洲影院色无极综合| 久久理论片午夜琪琪电影网| 国产精品久久激情| 国产精品视频久| 亚洲福利在线视频| 欧美一区第一页| 欧美成人精品在线播放| 精品国产一区二区三区四区在线观看| 亚洲白虎美女被爆操| 精品久久久久久久久久久久久| 欧美在线视频在线播放完整版免费观看| 亚洲欧美日韩爽爽影院| 国产精品99久久99久久久二8|