We can usefully be both a macro/operator and function under the same symbol:
This is the TXR Lisp interactive listener of TXR 268.
Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet.
1> (special-operator-p 'and)
t
2> (fboundp 'and)
t
3> (fun and)
#<intrinsic fun: 0 param + variadic>
4> (and 23 nil (prinl 42))
nil
5> (call 'and 23 nil (prinl 42))
42
nil
6> [and 23 nil (prinl 42)]
42
nil
7> [mapcar if '(nil t t nil) '(1 2 3 4) '(a b c d)]
(a 2 3 d)
8> (if t (prinl 'true) (prinl 'false))
true
true
9> [if t (prinl 'true) (prinl 'false)]
true
false
true
If we use the functional brackets, all arguments are evaluated the same way, and the leftmost value is treated as a callable object applied to the remaining values.A symbol in the leftmost position of [...] is never treated as a macro (other than symbol macro) or special operator, even if it has a such a binding.
Re:James Gosling Interview
by andrekandre on Thursday August 12, 2021 @05:52PM
(#28162022)
thanks, i think that makes it more clear for ^^
> (and a b c)
> (and* a b c)
Can you tell by looking that the the first is a macro and the second is a function? The first short circuits and evaluates only the argument forms it needs and the second always evaluates all three. That's a big difference, and not at all obvious from the syntax. In fact, it's hidden by the syntax, because the syntax is exactly the same for each.
Macros are part of the power of Lisp, but they change the normal rules of evaluation (the semantics) in ways that are not necessarily obvious unless you know the specific definitions behind each symbol in function position.