My goal is to evaluate an expression at compile time, like some simple things as (+ 1 1). But, I would like an integer "2" to be compiled in, instead of a full "1+1" operation to be done at runtime, without using a named macro. This makes my source code clearer showing how I got the value "2" while not wasting CPU time repeating the same "1+1" operation. Here is a simple example illustrating the basic idea but not for real cases, say, my ideal goal defun function looks like this:
(defun test ()
(+ 1 2 3))
I would like literal "2" to be evaluated at compile time so I use eval-when-compile:
(defun test ()
(+ 1
(eval-when-compile (+ 1 1))
3))
However, it turns out becoming:
(defun test ()
(+ 1 '2 3))
It's of course okay for this simple case but this extra quote is causing problems for more complicated cases.
Defining a named macro works:
(defmacro 1+1 () `,(+ 1 1))
(defun test ()
(+ 1 (1+1) 3))
It will produce my ideal result with no quote prepending the integer "2":
(defun test ()
(+ 1 2 3))
Is there a simple way like the above eval-when-compile to achieve this, in a defun? Something like an unnamed macro to get rid of the named helper 1+1, or should I call this "lambda macro"?
Inspired by the answer of @phils, I finally able to define anonymous macros and run them. I define a helper macro named immediate to help solving this; it basically defines an anonymous macro function temporarily using macrolet, then runs it:
(defmacro immediate (body)
"Define an anonymous macro and run it immediately"
(let ((f (make-symbol "immed")))
`(macrolet ((,f () ,body))
(,f))))
With immediate, I can rewrite the sample code in my original question this way:
(defun test ()
(immediate (concat "Docstring" " of " "test" ))
(+ 1
(immediate (+ 1 1))
3))
The test function will be defined exactly as what I expected it to be:
(defun test ()
"Docstring of test"
(+ 1 2 3))
(The name immediate is inspired by the immediate words from the Forth language.)