Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!UUNET.UU.NET!duff%eraserhead%steinmetz From: duff%eraserhead%steinmetz@UUNET.UU.NET (David A Duff) Newsgroups: gnu.emacs.lisp.manual Subject: eval.texinfo Message-ID: <8902101729.AA02252@eraserhead.steinmetz.GE.COM> Date: 10 Feb 89 17:29:41 GMT References: <8902091900.AA10391@m.cs.uiuc.edu> Sender: daemon@tut.cis.ohio-state.edu Reply-To: duff@eraserhead.steinmetz.ge.com Distribution: gnu Organization: GNUs Not Usenet Lines: 317 Dan, Here some input. I'd say this is still a little rough. I've given some suggestions, but you'll have to sort of smooth things over a bit if/after you insert some of my stuff. Once again, my comments begin at the left margin. Your original text is included for context. (Do you have some other way of getting corrections that you'd prefer?) Dave ============ @node Evaluation @chapter Evaluation Since Emacs Lisp is an interpreted language, evaluation takes the place of compiling, linking, and running in other languages. The @dfn{evaluation} of objects in Emacs Lisp invokes the @dfn{Lisp interpreter}. I suppose there are a number of ways that you could explain this, but I think the simplest would be to say that the eval function IS the interpretter. Also, evaluation doesn't really take the place of compilation in emacs lisp. There is a separate (though always optional) compilation phase, so it's not really accurate to say that evaluation "takes the place of" compilation. How about this: In most other programming languages, a program is usually thought of a string of text. This string of text must be parsed into some sort of machine readable form by a process called compilation. Typically, a number of separate program units require some type of "linking" process to combine them into one executable file, which is then run. In Lisp, on the other hand, a program is a lisp object (@xref{objects} [or whatever...]). We usually call lisp objects that are used as programs @dfn{forms} to distinguish them from lisp objects which are treated as data. To "run" a program in emacs lisp, we call the @code{eval} function on a form. The process performed by the @code{eval} function is called -- naturally -- @dfn{evaluation} and is the subject of this chapter. A description of @code{eval} essentially defines the semantics of the Emacs Lisp language. But rather than say that objects are evaluated, we say @dfn{forms} are evaluated. This is to emphasize the view of objects as code, rather than as data. Conversly, any piece of code in Lisp, i.e., an action to be performed, may also be manipulated as a piece of data. This is one of the fundamental differences between Lisp and most other programming languages. An Emacs Lisp program consists of a sequence of forms. The evaluation of forms must take place in a context. This context is called the @dfn{environment}. ok so far... It consists of the set of global symbols and the function call stack. The @dfn{call stack} is simply a list of stack frames, one for each nested function call. (What about let bindings?? Is "call stack" the appropriate term?) A @dfn{stack frame} contains, among other things, a list of bindings local to that function. (Variable bindings are described in @pxref{Local Variables}). Well, I don't like this stack frame business and it sounds like you don't either. How about this: Eval is a recursive function. The evaluation of a form can affect the results of subsequent calls to eval by either binding the values symbols (variables), creating new bindings for variables, and by affecting the flow of control in the program (@xref{...} [refer to non-local exits -- e.g. catch, throw, unwind- protect, etc.]). [then we'd need a short section on variables and binding. I won't go into this now, but I think it deserves a separate subsection, if for no other reason than to make it clear to people who think they know lisp (e.g. common lisp), that emacs lisp only has dynamic (as opposed to lexical) binding.] The environment also includes many other internal objects that are not directly accessible to Emacs Lisp, but they may often be affected when the appropriate primitive functions are called. I haven't any idea what you're referring to here. If they aren't accessible to emacs lisp, then what's the point of mentioning them here? Oh... maybe you are referring to control-flow type stuff (unwind-protects, and the like)? Naturally, many forms change the environment as a result of evaluating them (e.g., a new symbol may be created); these forms are said to produce @dfn{side-effects}. Evaluation of one particular function call, @code{byte-code}, invokes the @dfn{byte-code interpreter} on its arguments. The byte-code interpreter uses the same environment as the Lisp interpreter, and may invoke the Lisp interpreter. @xref{Byte Compilation} for the details. I wouldn't mention this yet. This is a side issue. Wait until we get the basics down first. @node Eval, Forms, , Evaluation @section Eval The functions and variables described in this section call the evaluator and define limits on the evaluation process itself. Explicit evaluation is also performed by @code{apply} and @code{funcall} (@pxref{Function Invocation}). What do you mean "explicit"? I think you must mean "implicit", right? The details of what evaluation means for each kind of form are described later; @pxref{Forms}. @defun eval form This is the basic function that performs evaluation. It evaluates @var{form} in the current environment, and returns the result. Since @code{eval} is a function, the argument is evaluated twice: once when the arguments of the function call are evaluated, and again by the @code{eval} function itself. The example illustrates this. @example (setq foo 'bar) @arrow bar (setq bar 'baz) @arrow baz (eval foo) @arrow baz @end example @end defun @defcmd eval-current-buffer &optional stream This built-in function evaluates the forms in the current buffer. @code{eval} is called repeatedly on successive forms until either the end of the buffer is reached or an error is signaled that is not handled. If @var{stream} is supplied, it is bound to @code{standard-output} (@pxref{standard-output}) during the evaluation. @code{eval-current-buffer} always returns @code{nil}. @end defcmd @defcmd eval-region start end &optional stream This built-in function evaluates forms in the current buffer in the region defined by the positions @var{start} and @var{end}. @code{eval} is called repeatedly on successive forms in the region until either the end of the region is reached, or an error is signaled that is not handled. If @var{stream} is supplied, it is bound to @code{standard-output} during the evaluation. I'm quite sure that you meant to say that @code{standard-output} is bound to @var{stream} and not vice versa. (They mean different things.) @code{eval-region} always returns @code{nil}. @end defcmd [...] @node List Forms, , Symbol Forms, Forms @subsection List Forms The first step in evaluating a list is examining its first element. (The empty list, which has no elements, is evaluated as the symbol @code{nil}.) The first element of the list should reference one of the following objects: a primitive function, a Lisp function, a Lisp macro, or an autoload object. By "reference" we mean that a symbol may appear that is associated with the object, as explained below. However, after this explanation, for simplicity we will say that the first element of the list @emph{is} one of these objects. Note that the first element of the list is @emph{not} evaluated, as it is in some Lisp-like languages (e.g. Scheme). If the first element of the list is a symbol, as it most commonly is, then the symbol's function cell is examined. If the object referenced by the function cell is another symbol, the function cell of that symbol is examined, and used exactly as if it had been the original symbol. This process, called @dfn{symbol indirection dereferencing}, continues until a non-symbol is found, and that object is called the @dfn{function definition} of all the symbols found along the way. But if a void function cell is encountered, the error @code{void-function} is signaled. @findex void-function @cindex void function (One possible consequence of this process is an infinite loop, if a symbol's function cell refers to the same symbol.) this is all fine, except that we seem to be spending a lot of words on a relatively obscure concept before we even understand the basics... If the first element of the list form is not a symbol, it may be a primitive function, Lisp function, Lisp macro, or autoload object. This object is used the same as if it had been found by the above dereferencing process. Do you, perhaps, want to xref the sections on these objects from the OBJECTS chapter? Once the symbol's function cell is finally dereferenced to an object that is not a symbol, it should be a primitive function, a Lisp function, a Lisp macro, or an autoload object. This is confusing, since we didn't necessarily start with a symbol -- we might have had an actual function object. this will need a little polishing up to make it flow together better. If any other kind of object is found, the error @code{invalid-function} is signaled. @findex invalid-function @xref{autoload} to find out how autoloading is done. Which object is found determines whether the rest of the elements in the list are evaluated. "Which object" ==> "Which type of object" For a Lisp function, all the elements are evaluated immediately. I'd make it explicit that this is a recursive call to eval, by saying: If the object is a function, then the eval function is called recursively on all of the rest of the elements in the list. But for a Lisp macro or primitive function, the rest of the elements are not necessarily evaluated. See the following sections for the details. [...] When a function call is evaluated, first the elements of the rest of the list are evaluated in the order they appear. Next, they are bound to the formal arguments of the function (@pxref{Local Variables} and @pxref{Lambda Expressions} for a complete description of the binding process). Last, the elements of the function body are evaluated, as if it were a @code{progn}, and the result of the function call is the value of the last element. Well, there's little point in saying "as though it were a progn" if you're going to say that they're evaluated in order and the last result is returned, anyway. The progn bit is not likely to be informative to people who are reading this. Since the actual arguments are evaluated in order, you could rely on this fact to produce side effects. This is poor programming style; instead, you should use an explicit sequential execution construct, such as @code{progn}. The two examples below produce the same results; the second one is far more readable. @example (list (setq x 1) (nth x '(cat rat mat))) @arrow (1 rat) (progn (setq x 1) (list x (nth x '(cat rat mat)))) @arrow (1 rat) @end example @node Lisp Macro Evalation, Primitive Function Evaluation, Lisp Function Evaluation, List Forms @subsubsection Lisp Macro Evaluation If the first element of a list being evaluated is a macro object, then that form is called a @dfn{macro call}. @xref{Macros} for the complete description of Emacs Lisp macros. When a macro call is evaluated, the elements of the rest of the list are @emph{not} initially evaluated; instead, they are bound to the formal arguments of the macro (@pxref{Macros} and @pxref{Lambda Expressions} for how this binding is done). Then the body of the macro is evaluated and the result is a new form, called the @dfn{macro expansion}. The macro expansion is then evaluated to produce the end result of the marco call. Since the macro expansion is evaluated, if it is itself another macro call, the process will be repeated. This recursive macro expansion continues until @code{max-lisp-eval-depth} (@pxref{max-lisp-eval-depth} is exceeded. To repeat, actual arguments to a macro are @emph{not} evaluated when the macro is called, but only if the macro body evaluates them explicitly, or if they are evaluated when the macro expansion is evaluated. This is the primary difference between functions and macros. @node @subsubsection Primitive Function Evaluation Looks like you're missing some information here. [...] @defun identity object This function returns @var{object} unchanged. But @var{object} is evaluated when @code{function} is called. @end defun I'm very confused as to why identity should appear here. It is not a special form. It is a function. @defspec quote object This special form returns @var{object}, without evaluating it. This allows symbols and lists, which would normally be evaluated, to be included literally in a program. (Note: It is not necessary to quote vectors since they always evaluate to themselves.) Use @code{function} instead of @code{quote} when quoting lambda expressions (@pxref{function}). Because @code{quote} is used so often in programs, a convenient read syntax is defined. An apostrophe character (@samp{@code{'}}) followed by a form expands to a list whose first element is @code{quote}, and whose second element is the form. Why is quote described here, while all of the other special forms are (apparently) described somewhere else? [...]