Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!sdd.hp.com!hplabs!otter.hpl.hp.com!otter!sfk From: sfk@otter.hpl.hp.com (Steve Knight) Newsgroups: comp.lang.lisp Subject: Re: In defense of call/cc (and a plug for T) Message-ID: <1350035@otter.hpl.hp.com> Date: 15 Feb 91 11:48:13 GMT References: <1991Feb12.233157.20820@elroy.jpl.nasa.gov> Organization: Hewlett-Packard Laboratories, Bristol, UK. Lines: 52 It's interesting to relate the discussion of call/cc to the experience of using "processes" in Poplog. (The "process" facilities in Poplog are a dual of the Scheme call/cc facilities in that each can be used to (fairly) directly implement the other.) Since the two facilities are very closely related -- I used Poplog "processes" to implement call/cc in my Scheme compiler -- the comparison is useful. From the viewpoint of implementation the key problem is dealing with what in Poplog is called dynamically-localised constructs -- which is a small generalisation of specials & sys-unwind-protect. As Barry points out in an earlier message: "And what about the fact that call/cc makes unwind-protect more complicated; don't you have to provide code that runs when re-entering the environment?" The interaction between thread switching and dynamic localisation really does complicate implementation, at least it does in Poplog. The issue to be decided is that when a process-switch occurs, the dynamic environment is exitted temporarily (or permanently), and dynamic localisations may or may not have to be reversed. Special-variables typically should be restored and sys-unwind-protect typically should be left alone. The solution adopted in Poplog is that by default, dynamic localisations are restored (i.e. put back to the state on entry) at thread-switch. However, there is a simple, rarely used, mechanism for localisations to inspect the kind of switching going on and to make a decision on the basis of that data. This is packaged up for sys-unwind-protect. A third strand to the overall solution that Poplog employs is "destroy actions". In Poplog, it is possible to associate an action with an object that is triggered when that object becomes eligible for garbage-collection. In particular, system resources such as file-handles or X-windows have associated clean-up actions so that if they are "lost" they are quietly shut down at the next garbage-collection (and actually collected next time around). Furthermore, file-opening code can cause a garbage-collection to happen if file-opening fails, in case the GC can reclaim the existing open files. Destroy actions are a slightly complicated topic -- which I've rather skimped on here to keep things short -- but they play an important role in reducing the necessity for sys-unwind-protect and other protective macros. Barry continues: > What if we were to add a coroutine facility, rather than a primitive for > building coroutines? See my previous posting, where I mentioned that we > prefer to define user-oriented facilities, rather than implementor-oriented > primitives. I certainly find programming using the Poplog "process" facilities to be a great deal more intuitive than call/cc. I instinctively find myself using call/cc to build a process-like layer. Since the two are interchangeable in expressive power, I'm inclined to think that the higher-level solution is more suitable for CL. Steve Knight HP Labs, Bristol