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

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

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

    莊周夢蝶

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

    Clojure的dosync是正則序?

    Posted on 2010-07-13 12:02 dennis 閱讀(2516) 評論(2)  編輯  收藏 所屬分類: 動態(tài)語言javaClojure

        解釋器求值的順序可以分為應(yīng)用序和正則序,應(yīng)用序是先求值參數(shù),再執(zhí)行表達式;正則序則是先將表達式按照實際參數(shù)展開,然后再執(zhí)行。具體可以看看過去寫的這篇文章

       Clojure的求值可以肯定是應(yīng)用序的,如執(zhí)行
    (defn mytest [a b] 
          (
    if (= a 0)
              a
              b))
    (mytest 
    0 1/0)
            

    盡管在(mytest 0 1/0)中a綁定為0,如果求值器是完全展開再求值,那應(yīng)該正常執(zhí)行并返回a,也就是1;但是因為clojure是應(yīng)用序,因此參數(shù)b的1/0會先計算,這顯然會報錯。

       clojure的dosync用于將一些表達式包裝成事務(wù),Ref的更新操作沒有包裝在事務(wù)里,會拋出異常
    ;;定義mutable的Ref
     (def song (ref #{}))

    ;;添加一首歌
    (alter song conj 
    "dangerous")

       alter用于向Ref查詢并添加元素,用conj將"dangerous"這首歌加入集合,但是alter要求執(zhí)行在一個事務(wù)里,因此上面的代碼會報錯
    java.lang.IllegalStateException: No transaction running (NO_SOURCE_FILE:0)

       如果你用dosync包裝就沒有問題
    user=> (dosync (alter song conj "dangerous"))
    #{
    "dangerous"}

       返回更新后的結(jié)果集合。這個跟我們要談的正則序和應(yīng)用序有什么關(guān)系呢?可能你看出來了,如果說clojure是應(yīng)用序,那么在表達式 (dosync (alter song conj "dangerous"))中,alter也應(yīng)該先執(zhí)行,應(yīng)當照樣報" No transaction running"的錯誤才對,為何卻沒有呢?難道dosync是按照正則序執(zhí)行?

       查看dosync的文檔
    user=> (doc dosync)
    -------------------------
    clojure.core
    /dosync
    ([
    & exprs])
    Macro
      Runs the exprs (in an implicit 
    do) in a transaction that encompasses
      exprs and any nested calls.  Starts a transaction 
    if none is already
      running on 
    this thread. Any uncaught exception will abort the
      transaction and flow out of dosync. The exprs may be run more than
      once, but any effects on Refs will be atomic.

       這是一個宏,他的作用是將表達式包裝在一個事務(wù)里,如果當前線程沒有事務(wù),那么就啟動一個。
    查看源碼:

    (defmacro dosync
      
    "Runs the exprs (in an implicit do) in a transaction that encompasses
      exprs and any nested calls.  Starts a transaction if none is already
      running on 
    this thread. Any uncaught exception will abort the
      transaction and flow out of dosync. The exprs may be run more than
      once, but any effects on Refs will be atomic.
    "
      [& exprs]
      `(sync nil 
    ~@exprs))

       本質(zhì)上dosync是調(diào)用了sync這個宏,sync干了些什么?
    (defmacro sync
      
    "transaction-flags => TBD, pass nil for now

      Runs the exprs (in an implicit 
    do) in a transaction that encompasses
      exprs and any nested calls.  Starts a transaction 
    if none is already
      running on 
    this thread. Any uncaught exception will abort the
      transaction and flow out of sync. The exprs may be run more than
      once, but any effects on Refs will be atomic.
    "
      [flags-ignored-for-now & body]
      `(. clojure.lang.LockingTransaction
          (runInTransaction (fn [] 
    ~@body))))

       找到了,原來是調(diào)用了clojure.lang.LockingTransaction.runInTransaction這個靜態(tài)方法,并且將exps包裝成一個匿名函數(shù)

    fn [] ~@body

         因此,dosync并非正則序,dosync是個宏,(dosync (alter song conj "dangerous"))展開之后,其實是
    (sync nil (fun [] (alter song conj "dangerous")))
       
         這就解答了為什么(dosync (alter song conj "dangerous"))可以正常運行的疑問。宏的使用,首先是展開,然后才是按照應(yīng)用序的順序求值。


      





    評論

    # re: Clojure的dosync是正則序?  回復(fù)  更多評論   

    2010-07-14 19:16 by clojans
    只是函數(shù)調(diào)用時才說是應(yīng)用序或正則序吧!

    # re: Clojure的dosync是正則序?  回復(fù)  更多評論   

    2010-07-14 20:30 by dennis
    @clojans
    恩,說的就是這么個事情,繞彎了
    主站蜘蛛池模板: 国产精品冒白浆免费视频| 在线观看免费a∨网站| 亚洲中久无码不卡永久在线观看| 亚洲日本VA中文字幕久久道具| 国产大片91精品免费观看不卡| 亚洲一区二区三区四区在线观看 | 亚洲日本中文字幕区| 十八禁视频在线观看免费无码无遮挡骂过| 国产一区二区免费在线| 国产亚洲精品第一综合| 亚洲一级特黄大片无码毛片| 亚洲五月午夜免费在线视频| 亚洲国产精品无码久久久秋霞2| 中文字幕免费不卡二区| 久久亚洲AV成人出白浆无码国产 | 亚洲欧美一区二区三区日产| 日韩在线看片免费人成视频播放| 亚洲精品日韩一区二区小说| 一本色道久久88亚洲综合| 亚欧乱色国产精品免费视频| 国产亚洲精品美女久久久| 99re6在线视频精品免费下载| 亚洲欧洲春色校园另类小说| 性xxxx视频播放免费| 美女无遮挡免费视频网站| 亚洲精品乱码久久久久久久久久久久 | 一级一看免费完整版毛片| 国产成人综合亚洲亚洲国产第一页| 可以免费观看的国产视频| 亚洲成人午夜电影| 日韩免费无砖专区2020狼| 国产精品九九久久免费视频| 亚洲专区先锋影音| 真实乱视频国产免费观看 | 久久亚洲精品中文字幕无码| 97在线视频免费公开观看| 亚洲乱妇熟女爽到高潮的片| 亚洲精品在线视频| 最近免费中文字幕mv在线电影| 亚洲6080yy久久无码产自国产| 国产亚洲精久久久久久无码|