common-lispbuilt-insbclslimecode-documentation

Is there a way to find out how the primitive functions (built-in) where exactly defined inside SBCL?


I am learning Common Lisp using Emacs, SBCL and Slime.

I would like to know exactly what is the code definition of the built-in functions.

I know how to use (documentation ...) and (describe ...). However, they provide only high level information. I would like to see the code details.

For instance, take the nth built-in function.

Documentation gives us:

CL-USER> (documentation 'nth 'function)
"Return the nth object in a list where the car is the zero-th element."

Describe gives me:

CL-USER> (describe 'nth)
COMMON-LISP:NTH
  [symbol]

NTH names a compiled function:
  Lambda-list: (SB-IMPL::N LIST)
  Declared type: (FUNCTION (UNSIGNED-BYTE LIST) (VALUES T &OPTIONAL))
  Derived type: (FUNCTION (T T) (VALUES T &OPTIONAL))
  Documentation:
    Return the nth object in a list where the car is the zero-th element.
  Inline proclamation: MAYBE-INLINE (inline expansion available)
  Known attributes: foldable, flushable, unsafely-flushable
  Source file: SYS:SRC;CODE;LIST.LISP

(SETF NTH) names a compiled function:
  Lambda-list: (SB-KERNEL::NEWVAL SB-IMPL::N LIST)
  Derived type: (FUNCTION (T UNSIGNED-BYTE LIST) (VALUES T &OPTIONAL))
  Inline proclamation: INLINE (inline expansion available)
  Source file: SYS:SRC;CODE;SETF-FUNS.LISP

(SETF NTH) has a complex setf-expansion:
  Lambda-list: (SB-IMPL::N LIST)
  (undocumented)
  Source file: SYS:SRC;CODE;DEFSETFS.LISP
; No value

I would like to see something like:

(unknown-command 'nth)

Which would return something like:

(defun nth (x xs)
  (if (equal x 0)
      (car xs)
      (my-nth (- x 1) (cdr xs))))

Lisp languages are fantastic and have a huge ecossystem built by awesome programmers. I hope there is some tool or command for that.

Thanks


Solution

  • When such information is available, it should be accessible via function-lambda-expression :

    * (FUNCTION-LAMBDA-EXPRESSION #'nth)
    (LAMBDA (SB-IMPL::N LIST)
      (DECLARE (SB-INT:EXPLICIT-CHECK)
               (OPTIMIZE SPEED))
      (BLOCK NTH
        (TYPECASE SB-IMPL::N
          ((AND FIXNUM UNSIGNED-BYTE)
           (BLOCK NIL
             (LET ((SB-IMPL::I SB-IMPL::N) (SB-IMPL::RESULT LIST))
               (TAGBODY
                LOOP
                 (THE LIST SB-IMPL::RESULT)
                 (IF (PLUSP SB-IMPL::I)
                     (PSETQ SB-IMPL::I (1- SB-IMPL::I)
                            SB-IMPL::RESULT (CDR SB-IMPL::RESULT))
                     (RETURN (CAR SB-IMPL::RESULT)))
                 (GO LOOP)))))
          (T (CAR (NTHCDR SB-IMPL::N LIST))))))
    NIL
    NTH
    

    However, it is not always available, in which case you would have to go to the SBCL source code repository.