Subject: Re: macro question From: Erik Naggum <erik@naggum.net> Date: Sun, 10 Mar 2002 19:54:35 GMT Newsgroups: comp.lang.lisp Message-ID: <3224778884977282@naggum.net> * Rolf Wester <rolf.wester@t-online.de> | This would be true for you but not necessaryly for a lisp beginner like | me. At present this is a problem for me. I know C++ well enough to be | able to do my work in a reasonable or at least predictable time. At | present I don't have the same confidence in my Lisp skills. In that case, it is encouraging that you try Common Lisp. (I started to use Common Lisp because C++ was just way too painful, and in the learning period, sustained myself as a journalist/columnist just to get away from programming computers for pay for a few years. It was that bad. :) | I guess I should learn about IA32 assembler. If you do, what you really need is a macro language that _works_, so producing assembly code using Common Lisp is the only way to go. | I read about compiler-maros before but have no clear understanding what | this is. Can you give me a link to somewhere I can learn more about it? Not really. They can be used to turn a function call into a macro call, such that the call is effectively expanded inline. Suppose that your maxwell-v-c1-c2 function does (* c1 v v (exp (* c2 v v ))), and that calling a function with three arguments would lose the type information the compiler is able to infer or has to been taught by you, and might even have to generic floating-point operations. If you had this function and decided that it would make sense to optimize this call, you could do (defun maxwell-v-c1-c2 (v c1 c2) (declare (double-float v c1 c2) (optimize (speed 3) (safety 0) (debug 0))) (* c1 v v (exp (* c2 v v)))) (defun maxwell-caller (v temp m) (declare (double-float v temp m) (optimize (speed 3) (safety 0) (debug 0))) (let ((c1 (* 4.0d0 dpi (expt (/ m (* 2.0d0 dpi +kB+ temp)) 1.5d0))) (c2 (/ (* -1.0d0 m) (* 2.0d0 +kB+ temp)))) (maxwell-v-c1-c2 v c1 c2))) This would need to box the double-float arguments, but could benefit from the fast, pure assembly code that is in the inner function. (define-compiler-macro maxwell-v-c1-c2 (v c1 c2) `(* c1 v v (exp (* c2 v v)))) This is an example of how to use compiler macros to inline user functions such that type inference and declarations still work. Some Common Lisp environments provide that functionality with a declaration to inline a particular function, but that is neither necessarily portable nor actually as effective. The biggest advantage of a compiler macro, however, is how it may be used to change a function call into something else. Suppose you have a function that takes any number of parameters, but it has a simple definition for, say, 0, 1, and 2 arguments, like + does. (define-compiler-macro + (&whole form &optional (arg-1 nil arg-1-p) (arg-2 nil arg-2-p) &rest arguments) (cond ((not arg-1-p) 0) ((not arg-2-p) arg-1) ((not arguments) `(internal-2-arg-+ arg-1 arg-2)) (t form))) A macro cannot decline to expand, but a compiler-macro can do just that by returning the whole form unchanged. This may or may not help... /// -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.