home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / misc / 2771 < prev    next >
Encoding:
Internet Message Format  |  1992-08-23  |  6.1 KB

  1. Path: sparky!uunet!mcsun!uknet!gdt!aber!aberfa!pcg
  2. From: pcg@aber.ac.uk (Piercarlo Grandi)
  3. Newsgroups: comp.lang.misc
  4. Subject: Re: Call/CC (Was Re: PL/1 non-local goto versus setjmp/longjmp)
  5. Message-ID: <PCG.92Aug23174319@aberdb.aber.ac.uk>
  6. Date: 23 Aug 92 17:43:19 GMT
  7. References: <1992Aug12.073130.1@zodiac.rutgers.edu> <id.VJBS.0DK@ferranti.com>
  8.     <mwm.1jk3@contessa.palo-alto.ca.us> <id.KTGS.0N5@ferranti.co
  9.     <DG.92Aug20172716@polly.dgupta.hpl.hp.com>
  10.     <mwalker-200892172501@mwalker1.npd.provo.novell.com.>
  11. Sender: news@aber.ac.uk (USENET news service)
  12. Reply-To: pcg@aber.ac.uk (Piercarlo Grandi)
  13. Followup-To: comp.lang.misc
  14. Organization: Prifysgol Cymru, Aberystwyth
  15. Lines: 113
  16. In-Reply-To: mwalker@novell.com's message of 20 Aug 92 23: 27:27 GMT
  17. Nntp-Posting-Host: aberdb
  18.  
  19. On 20 Aug 92 23:27:27 GMT, mwalker@novell.com (Mel Walker) said:
  20.  
  21. mwalker> I'm reading the r4rs report on Scheme, and this "Call with
  22. mwalker> current continuation" confuses the heck out of me. I can't
  23. mwalker> figure out what it's good for. Is it just kind of a
  24. mwalker> setjmp/longjmp? I guess I don't see the similarity people have
  25. mwalker> been posting about. Can anybody straighten me out on this?
  26.  
  27. Here I have rack and hot irons, ready for use. :-)
  28.  
  29. First, two references: John Allen, "Anatomy of Lisp"; Abelrson &
  30. Sussman, "Program structures".
  31.  
  32. Second, a small explanation:
  33.  
  34. All languages have implicit an environment graph and a control graph.
  35. Nodes in the environment graph are token-value associations, and nodes
  36. in the control graph are cpu-state frames.
  37.  
  38.   Low-level explanation:
  39.     Given a procedure, it is instantiated by creating a new environment
  40.     node, filling it out with the arguments, creating a new control node,
  41.     setting the PC in itr to the beginning of the procedure, and then
  42.     making it active instead of the one describing the currently running
  43.     procedure instance.
  44.  
  45. A given procedure may have many instances, e.g.  for recursion, and
  46. correspondingly many environment and control nodes may refer to it.
  47.  
  48. Procedure instances may be values that are passed around, or may not be.
  49.  
  50. Now, most languages have restrictions to ensure that the control and
  51. environment graphs are really trees, and that such trees can only be
  52. walked depth first. In other words that the control and environment
  53. trees can be implemented as a stack, as no procedure instance outlives
  54. the procedure instance that created it.
  55.  
  56. While the control and environment graphs are normally treated as
  57. linearized trees, in a FIFO fashion, there are at least two cases where,
  58. even in traditional languages, strict nesting must be violated. The two
  59. cases are procedure parameters (downward furnargs) and non local gotos
  60. (catch/throw or longjmp).
  61.  
  62. With procedure parameters, depending on the language, an environment
  63. frame is passed downwards, skipping several intermediate levels of the
  64. stack. With non local gotos, control is transferred upwards, skipping
  65. several levels of the stack.
  66.  
  67. Both facilities however are restricted to stack operation; procedure
  68. parameters cannot be passed upwards (except for particular cases) and
  69. control cannot be transferred downwards. The reasons are that,  in stack
  70. based implementations, if a reference to an environment node is passed
  71. upwards, the environment node will have been deallocated, and if a
  72. control transfer is done downwards, the control node will also have been
  73. deallocated.
  74.  
  75. However if environment and control nodes are made to exist in a non
  76. stack like fashion then environment nodes can be passed 'upwards' and
  77. control transfers can happen 'downwards'. An environment node that
  78. persists upwards is called a closure, and a control node that that
  79. persists downwards is called a continuation point.
  80.  
  81. Once these two entities can be manipulated, an entity called a
  82. continuation (or generator or coroutine, at times) can be assembled out
  83. of a continuation point and a closure. A continuation is just a
  84. procedure instance made persistent and resumable.
  85.  
  86. call/cc 'just' gives you a handle on the currently executing procedure
  87. instance. Or rather a copy of that, usually -- most scheme systems
  88. create procedure instances on the stack by default, and only in the
  89. relatively rare case where one uses call/cc the procedure instance gets
  90. copied to the heap; this is safe because procedure instance handles can
  91. only be gotten via call/cc. In older, dynamically scoped lisps, the
  92. function primitive could be used to obtain a closure, but that was all
  93. (in scheme, which is lexically scoped, it's define that is mostly used
  94. to create closures, statically that is).
  95.  
  96. Note that in scheme there is no direct way to get separate access to the
  97. environment and control node components of a procedure instance.
  98.  
  99. Now, what is the similarity between setjmp and call/cc?
  100.  
  101.   That setjmp creates a continuation point that can be resumed by some other
  102.   arbitrary procedure instance, as long as the resuming procedure instance
  103.   is newer than the resumed one. In other words setjmp/longjmp are an
  104.   escape, just like call/cc, from the strict nesting of procedure
  105.   call/return.
  106.  
  107. And what is the difference?
  108.  
  109.   There are two of them: setjmp defines only a continuation point, not a
  110.   closure (it even loses parts of the current closure, if 'volatile' is
  111.   not used!), while call/cc does both, and the continuation point defined by
  112.   setjmp cannot be passed upwards, while the continuation defined by
  113.   call/cc can.
  114.  
  115.  
  116. There is also another relationship of sorts between the two:
  117.  
  118.   In some implementations of call/cc there is some abuse of setjmp, where
  119.   it is used to define the control node of a continuation, even in a
  120.   downward sense, by second guessing setjmp's implementation and changing
  121.   stacks behind its back. This works, but is hardly portable.
  122.  
  123.  
  124. Finally, a small idea on what call/cc is good for. Well, to realize in
  125. scheme a lot of nice tricks, or rather fundamental concepts, like
  126. coroutines, streams, generators, classes, actors, exception handling,
  127. ... by letting you create arbitrary control and environment graphs.
  128. --
  129. Piercarlo Grandi                   | JNET: pcg@uk.ac.aber
  130. Dept of CS, University of Wales    | UUCP: ...!mcsun!ukc!aber-cs!pcg
  131. Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@aber.ac.uk
  132.