<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理

    應用序 or 正則序?

    Posted on 2007-05-08 15:11 dennis 閱讀(4387) 評論(6)  編輯  收藏 所屬分類: 計算機科學與基礎
        這是《計算機程序的構造與解釋》中的一道習題,如何去判斷一個scheme解釋器是采用什么方式進行求值的?應用序 or 正則序。應用序是先對參數求值而后應用,而正則序則相反——完全展開而后歸約求值。正則序相比于應用序,會部分存在重復求值的情況。習題是這樣的:
        Ben Bitdiddle發明了一種檢測方法,能夠確定解釋器究竟采用的哪種序求值,是采用正則序,還是采用應用序,他定義了下面兩個過程:
      
    (define (p) (p))
    (define (test x y)
        (
    if (= x 0)
             
    0
             y))
        而后他求值下列的表達式:
      
    (test 0 (p))
    如果解釋器采用的是應用序求值,ben將會看到什么情況?如果是正則序呢?

        分別分析下這兩種情況下解釋器的求值過程:
    1.如果解釋器是應用序,將先對過程test的參數求值,0仍然是0,(p)返回的仍然是(p),并且將無窮遞歸下去直到棧溢出,顯然,在這種情況下,解釋器將進入假死狀態沒有輸出。

    2.如果解釋器是正則序,完全展開test過程:
    (define (test 0 (p))
        (
    if (= 0 0)
            
    0
            (p))
    接下來再進行求值,顯然0=0,結果將返回0。

        一般lisp的解釋器都是采用應用序進行求值。這個問題在習題1.6中再次出現。我們知道scheme已經有一個cond else的特殊形式,為什么還需要一個if else的特殊形式呢?那么我們改寫一個new-if看看:
    (define (new-if predicate then-clause else-clause)
            (cond (predicate then
    -clause)
                  (
    else else-clause)))

    寫幾個過程測試一下:
    (new-if (< 1 01 0)
    結果一切正常,但是,當這3個參數是過程的時候會發生什么情況呢?在這3個參數如果存在遞歸調用等情況下,解釋器也將陷入無限循環導致棧溢出!比如書中的求平方根過程用new-if改寫:
    (define (new-if predicate then-clause else-clause)
            (cond (predicate then
    -clause)
                  (
    else else-clause)))
    (define (average x y)(
    / (+ x y) 2))
    (define (square x) (
    * x x))
    (define (improve guess x)(average guess (
    / x guess)))
    (define (good_enough
    ? guess x)
            (
    < (abs (- (square guess) x)) 0.000001))
    (define (sqrt_iter guess x)
            (new
    -if (good_enough? guess x)
                guess
                (sqrt_iter (improve guess x) x)))   
    (define (simple_sqrt x)(sqrt_iter 
    1 x))

    因為解釋器是應用序求值,將對new-if過程的3個參數求值,其中第三個參數也是一個過程(sqrt_iter (improve guess x) x)) 遞歸調用自身,導致無限循環直到棧溢出。




    評論

    # re: 應用序 or 正則序?  回復  更多評論   

    2008-09-22 22:45 by stephanxu@sina.com
    謝謝解答,腦瓜好久不用,銹掉了

    # re: 應用序 or 正則序?  回復  更多評論   

    2010-12-02 17:40 by baozii
    我覺得第二題和正則序&應用序沒有關系呢……

    即使是正則序也是會陷入死循環的

    解釋器這樣做的原因或許是因為三者都是作為函數的參數傳遞進去的,而解釋器會對每個函數的參數進行求值

    # re: 應用序 or 正則序?[未登錄]  回復  更多評論   

    2011-02-28 22:45 by 咸魚
    = =我還是分不清正則序跟應用序啊!!!!!!!

    # re: 應用序 or 正則序?  回復  更多評論   

    2013-03-10 00:53 by Victorique
    http://codepad.org/BDtSL4nR
    剛剛在看這一節,博主的文很有用,謝謝。
    呵呵看來codepad為應用序咯。

    # re: 應用序 or 正則序?  回復  更多評論   

    2014-06-09 17:52 by Muout
    @baozii
    確實,第一題是應用序存在的問題,但是第二道題不管正則序還是應用序,都會有這個問題;
    正則序完全展開時,會忽略條件,一直展開只至展開到基本元素,所以遇到由條件判斷結束的遞歸就沒法結束,一直在展開;
    應用序在調用用戶定義的普通過程時,會先計算所有的入參,不管這個入參會不會被使用到或者調用到,所以在遞歸中,也是因為計算值的需要一直在展開;

    所以,不管正則序還是應用序都需要特殊處理的if語句;

    # re: 應用序 or 正則序?[未登錄]  回復  更多評論   

    2015-01-05 17:41 by XXX
    @baozii
    第一題應用序,正則序都要跪!
    我也做了一個測試
    (define (add x) (if (< x 5000000) (add x) -5))
    然后是
    (define (mytest x y) (if (= x 0) 0 (add y)))
    然后運行
    (mytest 0 1)
    結果瞬間出現了0,證明沒有展開后面的(add y)
    但是運行(test 0 (p))的時候,跪了

    所以結論是,不管是正則序還是應用序,都要跪!
    主站蜘蛛池模板: 久久久久久久国产免费看| 爱情岛论坛亚洲品质自拍视频网站| caoporn国产精品免费| 免费欧洲毛片A级视频无风险| 亚洲美女免费视频| 精品国产麻豆免费人成网站| 亚洲色偷拍另类无码专区| a级毛片无码免费真人久久| 国产亚洲AV手机在线观看| 本道天堂成在人线av无码免费| 全部免费a级毛片| 免费无码国产在线观国内自拍中文字幕| 国产美女无遮挡免费视频网站| 国产精品亚洲专区在线播放 | 亚洲国产精品lv| 久久免费观看国产精品| 亚洲精品无码久久毛片波多野吉衣| 日韩精品内射视频免费观看 | 日本一道高清不卡免费| 国产亚洲男人的天堂在线观看| 免费看国产曰批40分钟| 一级特黄特色的免费大片视频| 亚洲AV综合色一区二区三区| 18禁美女裸体免费网站| 亚洲av片不卡无码久久| 在线a毛片免费视频观看| 污污的视频在线免费观看| 在线观看亚洲精品福利片| 日本免费高清视频| 亚洲一区二区三区在线| 免费一级毛片不卡不收费| 国产性生大片免费观看性| 亚洲欧洲日韩在线电影| 日韩a级毛片免费视频| 美女巨胸喷奶水视频www免费| 91午夜精品亚洲一区二区三区| 日韩高清免费在线观看| 99精品免费视品| 亚洲一区二区三区在线观看网站| www国产亚洲精品久久久| 午夜免费福利视频|