Yes, but as you indicated above, one can't always use a function,
because all of its arguments are expanded.
In SBCL:
(defun fif (condition true-part else-part)
(if condition
true-part
else-part))
(defvar x 0)
(fif (zerop x) 'inf (/ 1 x))
debugger invoked on a DIVISION-BY-ZERO:
arithmetic error DIVISION-BY-ZERO signalled
Operation was SB-KERNEL::DIVISION, operands (1 0).
NewLisp uses fexprs, which give you the best of both worlds.
(I'm not an expert in NewLisp, so this could be improved.)
(define-macro (fif condition true-part else-part)
(if (eval condition)
(eval true-part)
(eval else-part)))
> (setq x 0)
0
> (fif (zero? x) 'inf (/ 27 x))
inf
> (setq x 3)
3
> (fif (zero? x) 'inf (/ 27 x))
9
It works with map:
> (map fif (list true nil) '(222 333) '(6 7))
(222 7)
And the built-in "if" works with map:
> (map if (list true nil) '(222 333) '(6 7))
(222 7)
--
Premature optimization is the root of all evil.