Page 1 of 2

macro for looping over functions in a list

Posted: Wed Dec 15, 2010 12:39 pm
by imba
Given

Code: Select all

(defconstant functions
  '(1+
    1-))
,

I want to define a macro that expands into

Code: Select all

(+
(1+ 1)
(1- 1))
How do I manage this?

Re: macro for looping over functions in a list

Posted: Wed Dec 15, 2010 1:15 pm
by ramarren
Looping over a list of functions does not require a macro. It is unclear to me what you are trying to achieve.

Re: macro for looping over functions in a list

Posted: Wed Dec 15, 2010 1:20 pm
by imba
I want the functions to be called to be inlined.

Re: macro for looping over functions in a list

Posted: Wed Dec 15, 2010 1:32 pm
by ramarren
That looks like a probably unnecessary micro-optimization, but if you want to use a constant at compile time you have to wrap it in EVAL-WHEN to guarantee it is available at compile time, and then just use it.

Re: macro for looping over functions in a list

Posted: Wed Dec 15, 2010 1:40 pm
by nuntius
It appears that standard functions like MAP and REDUCE may solve your problem. A good implementation (for optimization) should have a compiler macro that identifies when these functions are passed constant parameters and can then inline the function calls for you.

What do the benchmarks look like without this inlined?

Re: macro for looping over functions in a list

Posted: Thu Dec 16, 2010 5:17 am
by gugamilare
imba wrote:I want the functions to be called to be inlined.
You don't need to worry about inlining simple standard functions. The functions 1+ and 1- are already inlined in most (all?) implementations.

If you created a function and want it to be inlined, use declaim

Code: Select all

(defun my-function (...)
  ...)

(declaim (inline myfunction))

Re: macro for looping over functions in a list

Posted: Thu Dec 23, 2010 4:53 am
by imba
In the following code,

Code: Select all

(defconstant functions '(1+ 1-)) 
(defun foo ()
  (loop for fun in functions 
           summing (funcall fun 4)))
1+ and 1- aren't inlined in foo. How can I achieve this?

Re: macro for looping over functions in a list

Posted: Thu Dec 23, 2010 8:58 am
by gugamilare
Only explicit calls to a function can be inlined. If you are holding functions in a variable, how can the compiler know which function that variable will be holding so that it can inline it? Unless the compiler makes really extraordinary analysis.

You can, however, optimize your code a little bit. The functions 1+ and 1- are supposed to work on integers, floats, rationals, complexes, etc. You can create your own version:

Code: Select all

(defun fixnum-1+ (x)
  (1+ (the fixnum x)))

(defun fixnum-1- (x)
  (1- (the fixnum x)))

(defconstant +functions+ '(fixnum-1+ fixnum-1-)) 
(defun foo ()
  (loop for fun in +functions+ 
           summing (funcall fun 4)))
Note that it is convention to use '+' around the name of constants, like +this+.

Re: macro for looping over functions in a list

Posted: Thu Dec 23, 2010 10:06 am
by imba
gugamilare wrote:Only explicit calls to a function can be inlined. If you are holding functions in a variable, how can the compiler know which function that variable will be holding so that it can inline it?
Well, because +functions+ is a constant? Is there no possibility to write a macro that translates this code to

Code: Select all

(+ (funcall 1+ 4)
    (funcall 1- 4))
?

Re: macro for looping over functions in a list

Posted: Thu Dec 23, 2010 11:08 am
by ramarren
Except the EVAL-WHEN issue I mentioned earlier this is a trivial list manipulation problem. If you don't know how to do that, you probably shouldn't be worrying about it, since, as it has been said, this is a microoptimization which is unlikely to achieve anything significant in most cases.