Search code examples
lispcommon-lisp

`NOT` is Not A Macro But A Function in Common Lisp


I don't know why NOT is defined as a function but a macro.
I've heard that function call may be cache-unfriendly.

Will it be better if NOT is a macro
The only reason I can think of is that a NOT function can be passed as value by adding #'.


Solution

  • not has the semantics of a function: its argument is evaluated perfectly normally (unlike, say, and and so on). It should therefore be a function: macros should be used only for things which cannot semantically be functions.

    Making not a function has benefits: simply because it is a function you don't need to write your own version every time you need a function with the semantics of not. Making not a function also has zero cost since the semantics of CL leave a compiler or interpreter entirely free to never actually call the function but rather generate inline code.

    Indeed you can see, for instance, in the SBCL sources that this is happening: in src/code/pred.lisp you will find

    (defun not (object)
      "Return T if X is NIL, otherwise return NIL."
      (not object))
    

    You can do this yourself, pretty much:

    (declaim (inline neg))
    
    (defun neg (x)
      (if x nil t))
    

    (And if you are really feeling your oats define a compiler macro as well, although I can't see any strong reason to do that here.)