Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!swrinde!elroy.jpl.nasa.gov!jato!granite!brian From: brian@granite.jpl.nasa.gov (Brian of ASTD-CP) Newsgroups: comp.lang.scheme Subject: Simulating Environments with Continuations ? Summary: How-to hints needed (a little long, too) Message-ID: <1991Jun27.192117.8609@jato.jpl.nasa.gov> Date: 27 Jun 91 19:21:17 GMT Sender: Brian Beckman Reply-To: brian@granite.Jpl.Nasa.Gov (Brian of ASTD-CP) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 82 Nntp-Posting-Host: granite.jpl.nasa.gov Hello, schemers. This is a little long, so hit 'n' if you're not interested in the subject... We here at JPL are striving to develop some GUI libraries for Scheme. We want to use object-oriented programming, specifically, multiple method inheritance. We very quickly ginned up something based on message-passing with superclass precedence lists, that works great. Sketchily, a class is represented by its constructor procedure. The constructor makes a lexical block con- taining instance variables and method procedures and returns a message-dispatching procedure. Like this: (define ( [args]) (let (( ) ( ) ...) (define ( ) ; reference ivars as free vars ) (define ( ) ; reference ivars as free vars ) ... (define (self msg [args]) (case msg (msg1 ) (msg2 ) ...)) self)) To instantiate an object (instance of a class), call the cons- tructor. The instance is represented by the message dispatch procedure ("self") returned. All the methods have access to the instance vars _via_ lexical scoping. Ok, the only problem is that each instance of a class will have its own copy of the method procedures. This is wasteful of space, since all the copies of each method proc are identical, having been "define"d by the same source code. What we want to do is solve the problem through method sharing. 1. We want the method procedures to be "define"d just once; 2. we want the names of the method procedures to be lexically hidden so they won't collide with global names; and 3. we want the method proc's to be able to access instance variables. As an approach to getting all these things, we've realized that encapsulating instance vars in first-class environments and passing the environments to method procedures would let us do #3. We could get #1 and #2 by encapsulating method proc definitions in an environment, too. Trouble is, environments are not part of Scheme. Some implementations have environments, it's true, but we can't afford to marry a product line; we have to go standard. We can imp- lement environments ourselves _a la_ metacircular evaluation (ch. 4 of SICP), but that takes us VERY far afield of what we're trying to do. Also, we can't use T because we can't port (the back end) of T. We are using "workstations of the future," i.e. we don't know now what machines we will want to run our software on. Therefore, we must have the source to our Scheme implementation and we must know ourselves how to port it. Currently, we're looking into the intersection of Scheme->C and Mit C Scheme (C Scheme has envi- ronments, but Scheme->C doesn't. Also, if we can't learn, by in- spection, how to port either or both of them to the TBD RISC machine of the future, then we'll look for something else like Elk or XScheme). So, how do we accomplish #1, #2, & #3 in std. Scheme? My intuition tells me that continuations, and some kind of continuation-passing style will do it, perhaps treating methods as co-routines, but I've been unable to devise a clean, simple way of doing it. Any suggestions would be welcome, either using continutations or some other technique that we've overlooked. \brian\ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Brian Beckman . . . . . . . . . . brian@granite.jpl.nasa.gov. . . . . . meta-disclaimer: every statement in this message is false . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .