Subject: Re: special forms. From: Erik Naggum <email@example.com> Date: Tue, 17 Jul 2001 11:49:39 GMT Newsgroups: comp.lang.lisp Message-ID: <firstname.lastname@example.org> * John Vert > However, just because something is evaluated doesn't mean it has to be > returned. In a language without any side-effects whatsoever, this is true. In such a language, evaluation _order_ has no meaning, either. No computation is entirely without side-effects, however. One nasty side-effect of every computation is that it consumes some small amount of energy and takes some small amount of time. This means that we cannot compute every possible outcome of every possible program for every possible input instantaneously, although the ability to do that would have been greatly appreciated by everyone but science fiction writers, who would have to think up something entirely different than the "what if energy were free" line of fantasizing. (Personally, I would have like some brilliant mind to have played with the concept of computational energy requiring human sacrifice and the moral implications of sacrificing life for knowledge. We already do this in terms of dedicating a hell of a lot of lives to science, and we accept some loss of life in the course of all discovery, but all of them are _accidental_. What if it had to be intentional? That is one (or several) science fiction stories I would love to read.) As long as you have side-effects, which means: as long as we are in what we currently understand to be "the real world", you need to be able to choose one and only one among several, possibly many, paths of execution, for a whole lot of practical and theoretical reasons alike. That means that you must have acute control over the evaluation of each particular subform of a conditional. The canonical example of this is where a function terminates on a condition. If both branches were evaluated, a program that simply output the contents of a file until it hit the end of the file would be like Schrödinger's "cat", you would not know if it had terminated until you looked at it. For instance, if a factorial function is defined thus: (defun factorial (n) (labels ((factorial-accomulator (n f) (if (plusp n) (factorial-accomulator (1- n) (* n f)) f))) (factorial-accomulator n 1))) each execution would both return and recurse, and this would never terminate, which means: There is no _one_ return value. Suppose for the sake of argument that this is not a problem. What should this return? (if (typep x '(integer 0 32)) (factorial x) (gamma (1+ x)) It is answers to questions like these that lead to the necessity of being able to control the evaluation of subforms. However, that having been said, it is very smart in today's very fast hardware, to delay the branching if you can compute both values at the same time and just use the one you need. In that case, we _are_ dealing with guaranteed side-effect-free computation (aside from the energy consumption, which, if a certain U.S. President persists, is not going to be a problem at all, no sirree), because not even machine registers, much less program variables, are affected by the simultaneous computation of both branches. It "only" requires very, very intelligent assembly coding. (As you may know, compilers were once considered to be AI-worthy problems. Today, code generators for modern processare are becoming so complex that human intelligence is inadqeuate to deal with them. I do not think we will see the next huge advance in computing until we teach our computers to build their own compilers, by which time these very intelligent computers will choose Lisp and every C-based programmer is left behind by evolution. That is C for Carbon, fellows. The next big programming language is going to be called "Si", pronounced the same way so we puny human brains will not feel so bad about it.) #:Erik -- If dolphins are so smart, but 250,000 of them drown each year when caught in huge fishing nets, why can we not teach them how to get themselves and others loose?