Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!usc!snorkelwacker.mit.edu!ai-lab!zurich.ai.mit.edu!jinx From: jinx@zurich.ai.mit.edu (Guillermo J. Rozas) Newsgroups: comp.lang.scheme Subject: Re: EVAL in Scheme Message-ID: Date: 6 Mar 91 13:53:15 GMT References: <13781@asylum.SF.CA.US> <1991Mar6.004022.26316@cs.ubc.ca> Sender: news@ai.mit.edu Reply-To: jinx@zurich.ai.mit.edu Organization: M.I.T. Artificial Intelligence Lab. Lines: 89 In-reply-to: manis@cs.ubc.ca's message of 6 Mar 91 00:40:22 GMT In article <1991Mar6.004022.26316@cs.ubc.ca> manis@cs.ubc.ca (Vincent Manis) writes: b) Scheme, as defined in R^3.9999999999999S, has semantics which do not require an implementation to maintain the names of bindings, or to allow environments to be manipulated by the programmer. This was deliberately done, to allow Scheme programs to be compiled efficiently. There is *no* way to "trick" Scheme into evaluating lists as programs, unless the implementation provides an eval procedure. You are confusing the issues of efficiency and flexibility. It is perfectly possible to have first-class environments and EVAL, and have efficient compilation. The ORBIT T compiler, and the MIT Scheme Liar compiler accomodate both, and I am quite confident in claiming that none of the performance problems that either implementation has are due to first-class environments or EVAL. In other words, it is feasible (and not too hard) to build an implementation where you only pay for the cost of these features if you use (or ``abuse'') them, and you don't when you don't use them at all. It does make the implementor's job a little harder, however. I generally regard a request from a programmer for eval with the same degree of suspicion that I would give a request from a civil engineer for a little bit of chewing gum to prop up one end of a bridge. eval is extremely dangerous in real programs, as the following hypothetical dialogue (from a system written in Scheme, but using eval) might demonstrate: Welcome to the nuclear reactor control system! You have been given VISITOR privileges. > Blow up reactor You are not authorized to do that. > -debug- Enter expression: (blow-up-nuclear-reactor!) Initiating destruct sequence... When you eval something, you are letting that expression have full access to the internal state of your program. If the form being evaled was typed in by a user, that user gets to do what s/he likes to your program. If the form being evaled wasn't written by a user, then you most likely can trivially restructure your program to eliminate eval, given Scheme's rich procedure composition facilities. eval allows people to do to your program what Robert Morris did to sendmail, using exactly the same technique as he used, namely "smuggling" a command into a system. I regard eval as the computational equivalent of unprotected sex, and treat it accordingly. Aren't you exagerating a bit? You are confusing the issues of modularity and dynamic access to the name space. Perhaps what you are saying is that the application program did not hide its internal state sufficiently given that it was making EVAL available. Consider the following two options: - On a Scheme with first-class environments, an environment can be created with only those bindings that we want users to see, and use EVAL exclusively with respect to that. Thus if this environment does not provide access to BLOW-UP-NUCLEAR-REACTOR! or to any other environment from which it is reachable, there is no danger. - On a Scheme without them, presumably EVAL evaluates with respect to the global environment. You can always write an application to export a limited set of procedures to the global environment, and if you do not export the ``dangerous'' procedures, there is still no way to get them. This, of course, also works in a Scheme with first-class environments, but is cruder than needed there. In other words, you can break poorly organized programs in many ways. Don't impose a straight jacket on all programmers just because bad programmers exist. Finally, if you really want to use eval in a portable program, write your own. Abelson and Sussman, as well as my forthcoming book, describe the subject of writing evaluators in great detail; a custom evaluator can do all sorts of error checking, and can restrict the user, in whatever ways you want. I have no objection against writing your own evaluators, and often EVAL is used out of laziness, but there is nothing wrong with that. One of the great features of Lisp is that interactive applications don't have to write their own parsers, output routines, or even evaluators for extension languages, so you can concentrate on the core of the application and not on accidental details. In other words, your argument is like saying that you should use your own parser instead of READ, and your own output routines instead of WRITE (and FORMAT). You can certainly do that, but you can get a program up much more quickly if you use the more powerful facilities available in Lisp than if you have to write them from scratch as you would have to in C or Pascal.