Subject: access to declaration information? From: Erik Naggum <clerik@naggum.no> Date: 1998/03/13 Newsgroups: comp.lang.lisp Message-ID: <3098779525464968@naggum.no> when writing highly optimized code, it is important to bind a variable to values of a single type so the compiler can optimize out the (redundant) type dispatch or checks, but however useful this may be, it is not quite sufficient for speed when macros use local variables that bound to the values, yet cannot "inherit" the known type restrictions into their own declarations. e.g., DOTIMES can easily optimize the representation of the counter variable if the upper bound is a constant fixnum, but if the upper bound is an expression that ought to be a constant fixnum because the compiler has already been informed of the relevant types and values involved, like the length of a vector that has been declared with a size, it's out of luck, and must use generic integer arithmetic. in traversing a vector, I wouldn't want to use the stupid C-approach and use DEFCONSTANT to define a symbol to hold the size and sprinkle that symbol around the code, I want to use (LENGTH <vector>) and that should be a constant if <vector> is in a scope with, say, (DECLARE (TYPE (VECTOR * 256) <vector>)), and variables whose values are tall taken from the set of indexes into this vector should be automatically declared (INTEGER 0 256). also, I want a macro-expansion function to be able to make the appropriate declarations by querying the environment for the declaration of the subexpressiosn involved. relying on the compiler to optimize away multiple layers of general macro-expansion code to divine the appropriate clauses that fit the type is just too optimistic. suppose I have a vector or some kind, and want to utilize SVREF when the vector is a simple vector. if I could know that the vector is simple in function calls that take this vector as argument, I could write a compiler macro to differentiate between the simple-vector case and the general case. if I knew some index arguments were declared to be less than the length of the vector, I could skip both bignum tests and range checks, but I would still want them if the function is called when I don't know that. I could use generic functions that specialize on all the argument types and _hope_ the compiler does compile-time dispatch to methods when it knows the types of all the arguments, but this, too, is removing some of the control that you want when your code is going to be squeezed to the last drop of performance. of course, you could write your own functions that encode the types of the arguments like som manual C++ name-mangler and write all optimized code with them, but that is _so_ disgusting. this may sound (too) hairy for Lisp, but this is the kind of stuff that strongly typed languages so readily exploit. if it were available for Lisp, too, the programmer and the compiler could cooperate on the speed of the code, instead of the programmer guessing and hoping he knows what makes the compiler happy enough to produce optimal code. am I out of luck? (note: other languages with these properties are not interesting at this time. Common Lisp doesn't get better by leaving it whenever you need something that isn't readily available, and porting applications to another language is not an option, anyway.) #:Erik -- God grant me serenity to accept the code I cannot change, courage to change the code I can, and wisdom to know the difference.