游.程 2009-03-04 22:30 采纳率: 0%
浏览 294
已采纳

Call / 抄送是什么?

I've tried several times to grasp the concept of continuations and call/cc. Every single attempt was a failure. Can somebody please explain me these concepts, ideally with more realistic examples than these on Wikipedia or in other SO posts.

I have background in web programming and OOP. I also understand 6502 assembly and had a minor randez-vous with Erlang. However still, I can't wrap my head around call/cc.

转载于:https://stackoverflow.com/questions/612761/what-is-call-cc

  • 写回答

10条回答 默认 最新

  • 10.24 2009-03-04 22:41
    关注

    Look, i've found this Continuation Passing Style best description on this topic.

    Here's stripped of details copy of that article:

    Author: Marijn Haverbeke Date: July 24th 2007

    Scheme's call-with-current-continuation function makes it possible to capture a computation, a state of the call stack as it were, and resume that same state at a later time. On top of such a primitive, various form of exception handling and C-like longjmp tricks can be implemented.

    function traverseDocument(node, func) {
      func(node);
      var children = node.childNodes;
      for (var i = 0; i < children.length; i++)
        traverseDocument(children[i], func);
    }   
    
    function capitaliseText(node) {
      if (node.nodeType == 3) // A text node
        node.nodeValue = node.nodeValue.toUpperCase();
    }
    
    traverseDocument(document.body, capitaliseText);
    

    This can be transformed as follows: We add an extra argument to every function, which will be used to pass the function's continuation. This continuation is a function value representing the actions that must happen after the function 'returns'. The (call) stack becomes obsolete in continuation-passing style ― when a function calls another function, that is the last thing it does. Instead of waiting for the called function to return, it puts any work it wants to do afterwards into a continuation, which it passes to the function.

    function traverseDocument(node, func, c) {
      var children = node.childNodes;
      function handleChildren(i, c) {
        if (i < children.length)
          traverseDocument(children[i], func,
                           function(){handleChildren(i + 1, c);});
        else
          c();
      }
      return func(node, function(){handleChildren(0, c);});
    }
    
    function capitaliseText(node, c) {
      if (node.nodeType == 3)
        node.nodeValue = node.nodeValue.toUpperCase();
      c();
    }
    
    traverseDocument(document.body, capitaliseText, function(){});
    

    Imagine we have a huuuuge document to capitalise. Just traversing it in one go takes five seconds, and freezing the browser for five seconds is rather bad style. Consider this simple modification of capitaliseText (don't pay attention to the ugly global):

    var nodeCounter = 0;
    function capitaliseText(node, c) {
      if (node.nodeType == 3)
        node.nodeValue = node.nodeValue.toUpperCase();
    
      nodeCounter++;
      if (nodeCounter % 20 == 0)
        setTimeout(c, 100);
      else
        c();
    }
    

    Now, every twenty nodes, the computation is interrupted for a hundred milliseconds to give the browser interface a moment to respond to user input. A very primitive form of threading ― you can even run multiple computations at the same time like this.

    A more commonly useful application of this is related to XMLHttpRequests, or the various IFRAME and SCRIPT tag hacks used to simulate them. These always require one to work with some kind of call-back mechanism to handle the data that the server sends back. In simple cases, a trivial function will do, or a few globals can be used to store the state of the computation that must be resumed after the data comes back. With complex cases, for example when the data is being used by a function that must return some value to its caller, continuations simplify things considerably. You just register the continuation as the call-back, and your computation is resumed when the request finishes.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(9条)

报告相同问题?

悬赏问题

  • ¥15 目详情-五一模拟赛详情页
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line